Transactions 将事务保持在Spring集成流中

Transactions 将事务保持在Spring集成流中,transactions,spring-integration,Transactions,Spring Integration,内置网关: <int-http:inbound-gateway id="inbound.gateway" request-channel="transactional.channel.input" reply-channel="channel.output" error-channel="channel.error"

内置网关:

<int-http:inbound-gateway   id="inbound.gateway"
                            request-channel="transactional.channel.input"
                            reply-channel="channel.output"
                            error-channel="channel.error"
                            request-payload-type="java.lang.String"
</int-http:inbound-gateway>

如果是注入代码的MessagingGateway,您只需在gateway启动事务,因为所有通道都是直接的,所以整个流程将在同一事务中运行。只需使用
@Transactional
注释网关方法,并将
@EnableTransactionManagement
添加到上下文(和事务管理器)中即可

或者,如果您希望事务中有其他内容,您可以更早地启动事务

@Transactional
public void foo() {
    ...
    Object reply = myGateway.exchange(Object foo);
    ...
}
只需确保从另一个bean调用
foo()
,以便包含
foo()
的类包装在事务代理中(通过@EnableTransactionManagement或


如果是http入站网关之类的网关,请在入站网关之后添加一个
@Transaction
al网关以启动事务。(添加一个服务激活器,它
ref
s a
,交换
消息
,并用
@Transactional
注释)。

不编写任何Java代码,还有一个神奇的技巧:

<channel id="input"/>

<aop:config>
    <aop:advisor advice-ref="txAdvice" pointcut="bean(input)"/>
</aop:config>

<tx:advice id="txAdvice">
    <tx:attributes>
     <tx:method name="send"/>
    </tx:attributes>
</tx:advice>


这样,您的所有直接单线程消息流将被包装到发送到通道输入的消息上的TX上,这取决于您的流是如何开始的-您在
v1.getEvent.channel.input的上游有什么
v1.getEvent.channel.input
作为输出通道,所以:
(入站网关)
->
(链)
->
(我已经发布了代码)
感谢您的回复!我终于选择了Artem解决方案,但还是要感谢:)嗨,Artem。返回此主题以确保。我将这种方法用于链输入通道,因此在链完成时将进行事务提交,对吗?因为我意识到,当我在持久化后请求它时,对象id是空的,但它正确地存储在DB中。对,因为底层链通道的所有其他
send
都是在
输入
通道的线程内完成的。嗨,我已经更改了问题以向您显示mi当前的简化上下文,因为当链完成时事务没有被执行(我已经用ecliselink精细日志确认)。Antonio,如果您开始新的问题,它会更好。但看起来你误解了我的答案。事务被绑定到方法调用周围的线程。在您的例子中,它是“transactional.channel.input”bean的“send()”。但是,如果所有其他通道都直接在下游流中,那么所有其他“发送”和“handleMessage”都将在该事务中。为了实现您对TX提交的要求,您将“非事务性通道输入”设置为执行器通道或队列。希望它是清楚的,我已经编辑了它,因为我认为其他人与此相关的情况下,可以看到新的例子最容易…抱歉无论如何。顺便说一句,我发现objectid为null这是一个与merge方法相关的问题,所以它工作得很好:)
<int:chain input-channel="transactional.channel.input" output-channel="non.transactional.channel.input>
    <int:service-activator ref="v1.registerUser.service" method="registerUser"/>
    <int:service-activator ref="v1.saveObject.service" method="saveObject"/>
</int:chain>
<int:chain input-channel="non.transactional.channel.input" output-channel="channel.output">
    <int:service-activator  ref="v1.getObjectId.service" method="getObjectId"/>
    <int:object-to-json-transformer/>
</int:chain>
@Transactional
public void foo() {
    ...
    Object reply = myGateway.exchange(Object foo);
    ...
}
<channel id="input"/>

<aop:config>
    <aop:advisor advice-ref="txAdvice" pointcut="bean(input)"/>
</aop:config>

<tx:advice id="txAdvice">
    <tx:attributes>
     <tx:method name="send"/>
    </tx:attributes>
</tx:advice>