如何在Java DSL集成流程中添加事务支持

huangapple go评论70阅读模式
英文:

How to add transaction support to Java DSL integration flows

问题

我需要为一个集成流程添加事务支持。假设有3个转换器。第一个和第三个转换器应该在同一个事务中完成,但第二个不应该在任何事务中完成。因此,如果第三个转换器出现错误,第一个和第三个转换器的所有更改都不应该被提交,但第二个转换器的更改应该被提交。我该如何做到这一点?我尝试添加.transform(FirstMessageTransformer, e -> e.transactional(true)),但然后所有的转换器都在一个事务中完成。我还尝试添加.transform(FirstMessageTransformer, e -> e.transactional(false)),但似乎不起作用,因为即使发生异常,所有转换器的更改都会被提交。

@Bean
public IntegrationFlow myMessageFromMessageAmqpInboundFlow() {
    return IntegrationFlows.from(myInboundChannel)
            .transform(FirstMessageTransformer, e -> e.transactional(true))
            .transform(SecondMessageTransformer)
            .transform(ThirdMessageTransformer, e -> e.transactional(true))
            .channel(anOutputChannel)
            .get();
}

上述代码中,我在第一个和第三个转换器上使用.transactional(true)来启用事务,而在第二个转换器上没有使用它,这样可以满足您的需求。

英文:

I have to add a transaction support to an integration flow. Let's assume that there are 3 transformers. The first and third transformers should be done within the same transaction, but the second one shouldn't be done within any transaction. Thus, if an error occurs in the third transformer, all changes from the first and third transformers should not be committed but changes from the second transformer should be committed. How can I do that? I tried to add .transform(FirstMessageTransformer, e -> e.transactional(true))but then all transformers are done within a transaction. I tried also to add .transform(FirstMessageTransformer, e -> e.transactional(false))but it doesn't seem to work well, because the changes are committed for all tranformers, even if an exception occurs.

@Bean
public IntegrationFlow myMessageFromMessageAmqpInboundFlow() {
    return IntegrationFlows.from(myInboundChannel)
            .transform(FirstMessageTransformer)
            .transform(SecondMessageTransformer)
            .transform(ThirdMessageTransformer)
            .channel(anOutputChannel)
            .get();
}

答案1

得分: 2

请尝试以下方式:

            .transform(FirstMessageTransformer, e -> e.transactional(true))
            .transform(SecondMessageTransformer, 
                            e -> e.transactional(
                                         new TransactionInterceptorBuilder()
                                                 .transactionManager(txManager)
                                                 .propagation(Propagation.NOT_SUPPORTED)
                                                 .build()))
            .transform(ThirdMessageTransformer)

这样,您将在以 FirstMessageTransformer 开头的整个子流程中拥有一个事务,而 Propagation.NOT_SUPPORTED 将告诉 SecondMessageTransformer 暂停当前事务,并仅在此事务之外执行此 MessageHandler。在完成与 SecondMessageTransformer 的工作后,原始事务应恢复并继续进行余下的流程。

英文:

Try like this:

        .transform(FirstMessageTransformer, e -> e.transactional(true))
        .transform(SecondMessageTransformer, 
                        e -> e.transactional(
                                     new TransactionInterceptorBuilder()
                                             .transactionManager(txManager)
                                             .propagation(Propagation.NOT_SUPPORTED)
                                             .build()))
        .transform(ThirdMessageTransformer)

This way you will have a transaction for the whole sub-flow starting with FirstMessageTransformer and that Propagation.NOT_SUPPORTED will say for the SecondMessageTransformer to suspend the current transaction and perform only this MessageHandler out of transaction. After finishing work with the SecondMessageTransformer, the original transaction should resume and continue for the rest of the flow.

huangapple
  • 本文由 发表于 2020年9月28日 21:33:46
  • 转载请务必保留本文链接:https://go.coder-hub.com/64103231.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定