我有一个消息驱动的通道适配器,配置为从队列中选择消息并将确认设置为事务处理。是否有可能向不同的队列发送不同的消息,同时保持相同的事务流也在数据库之间进行插入?如果邮件传递失败到任何队列,则事务必须回滚(包括数据库条目)以及将邮件发送到其他队列。
示例:queue(receive)---> insert Db - > send to(queue1,queue2 .. etc,向每个队列发送不同的消息)
如果对queue1,queue2等的任何发送调用失败,则事务应该回滚...
我可以使用单个队列进行配置(即仅使用queue1)。但是如果涉及多个队列并保持事务边界,该怎么做。
由于 维迪
以下是配置
<int-jms:message-driven-channel-adapter
id="MessageDrivenAdapter" channel="injmsChannel" destination="testQ"
concurrent-consumers="5" max-concurrent-consumers="10" acknowledge="transacted"
error-channel="Error" />
<int:channel id="injmsChannel" />
<int:chain input-channel="injmsChannel" id="Chain1">
<int-jpa:retrieving-outbound-gateway
entity-class="entity.TestTable8"
entity-manager-factory="entityManagerFactory" id-expression="payload.getSno()">
<int-jpa:transactional transaction-manager="transactionManager" />
</int-jpa:retrieving-outbound-gateway>
<int:recipient-list-router id="ROUTE_1_2">
<int:recipient channel="SuccessChannel"
selector-expression="payload.getSno()==1" />
/> -->
</int:recipient-list-router>
</int:chain>
<int:channel id="SuccessChannel" />
<int:chain id="MessageProcessingChain" input-channel="SuccessChannel"
output-channel="putMsgChannel">
<int:service-activator id="a1" ref="taskexe"
method="processTable8_1" requires-reply="true" />
<int-jpa:retrieving-outbound-gateway
id="table7" entity-class="entity.TestTable7"
entity-manager-factory="entityManagerFactory" id-expression="payload.getSno()">
<int-jpa:transactional transaction-manager="transactionManager" />
</int-jpa:retrieving-outbound-gateway>
<int:service-activator id="a2" ref="taskexe"
method="processTable8_2" requires-reply="true" />
<int-jpa:updating-outbound-gateway
id="table6" entity-class="entity.TestTable6"
entity-manager-factory="entityManagerFactory" flush="true">
<int-jpa:transactional transaction-manager="transactionManager" />
</int-jpa:updating-outbound-gateway>
<int:service-activator id="a3" ref="taskexe"
method="processTable6_1" requires-reply="true" />
<int-jpa:updating-outbound-gateway
id="uptable6" entity-class="entity.TestTable6"
entity-manager-factory="entityManagerFactory" flush="true">
<int-jpa:transactional transaction-manager="transactionManager" />
</int-jpa:updating-outbound-gateway>
<int:service-activator id="a4" ref="taskexe"
method="processTable6_2" requires-reply="true" />
<int-jpa:updating-outbound-gateway
id="uptable4" entity-class="entity.TestTable4"
entity-manager-factory="entityManagerFactory" flush="true">
<int-jpa:transactional transaction-manager="transactionManager" />
</int-jpa:updating-outbound-gateway>
<int:service-activator ref="taskexe" method="processTable4_1"
requires-reply="true" />
</int:chain>
<int:channel id="putMsgChannel" />
<int-jms:outbound-channel-adapter id="sendsomemsg"
channel="putMsgChannel" connection-factory="connectionFactory"
session-transacted="true" destination-expression="headers['somequeue']" />
如何为具有消息驱动适配器的相同事务边界的其他队列添加另一个int-jms:outbound-channel-adapte?还设置了flush = true,以便在有任何jpa适配器异常时不向下游传递消息。
答案 0 :(得分:1)
只要使用JmsTemplate
(包括使用JMS出站通道适配器)执行队列发送,在同一个线程上,它们将在与消息驱动适配器相同的事务会话中执行消息传递。
如果将JDBC事务管理器添加到消息驱动的适配器,其事务将与JMS事务同步。
这提供了{Best 3>}中讨论的“尽力而为1PC”。
数据库提交成功并且JMS提交失败的可能性很小,因此您需要处理重复项。为了避免这种情况,您需要一个完整的XA解决方案。