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>