Java 使用Spring集成实现MongoDB入站流

Java 使用Spring集成实现MongoDB入站流,java,spring-integration,spring-integration-dsl,Java,Spring Integration,Spring Integration Dsl,我们将有一个包含多个工作单元的Mongo集合。我的想法是,文档将有一个状态字段,其中有四个选项:未处理、正在处理、完成、失败。Spring集成将被配置为从该数据库读取并处理存储在其中的消息 入站Mongo DSL流将基于未处理的值从集合中读取: MongoDbMessageSource messageSource = new MongoDbMessageSource(mongo, new LiteralExpression("{'status' : 'UNPROCESSED'}")); retu

我们将有一个包含多个工作单元的Mongo集合。我的想法是,文档将有一个状态字段,其中有四个选项:未处理、正在处理、完成、失败。Spring集成将被配置为从该数据库读取并处理存储在其中的消息

入站Mongo DSL流将基于未处理的值从集合中读取:

MongoDbMessageSource messageSource = new MongoDbMessageSource(mongo, new LiteralExpression("{'status' : 'UNPROCESSED'}"));
return IntegrationFlows.from(messageSource)...
问题是:如果我有几个工作机器从同一个数据库读取数据,我希望阻止它们在相同的未处理数据行上运行,因为我的轮询器对
maxMessagesPerPoll
使用保守值,或者消息处理需要一段时间

似乎正确的做法是使用
TransactionSynchronizationFactory
定义一个ProcessBeforeCommit阶段将状态更新为PROCESSING,以及一个ProcessAfterCommit阶段将状态更新为DONE或FAILED。然而,在查看轮询器和TransactionManager的API时,我并不清楚添加此功能的机制。XML中有一些示例,但我看不到任何使用DSL的示例


我还想确保ProcessBeforeCommit发生在读取数据库时,而不是在处理之后。。。是吗?此外,如果这不是设计从Mongo集合读取的解决方案的最佳方式,请随意建议更好的体系结构。

否,
ProcessBeforeCommit
ProcessAfterCommit
是非常接近的回调。它们肯定会在你的过程结束时发生。让我们假设你有一个方法:

@Transactional
void foo() {}
当您调用这样一个方法时,事务在进入方法体之前开始。 当我们在方法体执行后退出它时,将执行beforeCommit回调。它可能会失败,因为在我们的过程中,外部连接(DB?)可能会丢失。只有当它正常时,我们才能在提交后继续执行

您可以通过
AbstractMessageSourceAdvice
implementation:来完成请求。因此,在
afterReceive()
实现中,您可以将文档更新为
处理
,甚至决定返回
null
而不是消息:仅仅因为它在数据库中的状态已经是
处理
。这样的
建议
可以注入
轮询器spec

/**
 * Specify AOP {@link Advice}s for the {@code pollingTask}.
 * @param advice the {@link Advice}s to use.
 * @return the spec.
 */
public PollerSpec advice(Advice... advice) {
/**
 * Specify the {@link TransactionSynchronizationFactory} to attach a
 * {@link org.springframework.transaction.support.TransactionSynchronization}
 * to the transaction around {@code poll} operation.
 * @param transactionSynchronizationFactory the TransactionSynchronizationFactory to use.
 * @return the spec.
 */
public PollerSpec transactionSynchronizationFactory(
完成
失败
确实可以通过应用于
轮询器规范的
事务同步FactoryBean
实现:

/**
 * Specify AOP {@link Advice}s for the {@code pollingTask}.
 * @param advice the {@link Advice}s to use.
 * @return the spec.
 */
public PollerSpec advice(Advice... advice) {
/**
 * Specify the {@link TransactionSynchronizationFactory} to attach a
 * {@link org.springframework.transaction.support.TransactionSynchronization}
 * to the transaction around {@code poll} operation.
 * @param transactionSynchronizationFactory the TransactionSynchronizationFactory to use.
 * @return the spec.
 */
public PollerSpec transactionSynchronizationFactory(

我觉得更好的解决方案是配置MongoDBMessageSource类,使其能够执行updateQuery而不仅仅是查询。如果你认为这是个好主意,我可以为此做公关。听起来真的很好。是的:这是完全自然的,并且与我们在
JdbcPollingChannelAdapter
中的内容一致。但这也不是第一次请求:。感谢您考虑以下贡献: