我正在调查在ServiceMix(v4.4.2)中运行的camel事务。以下是我的路线:
from(WEBSERVICE_CAMEL_ENDPOINT).to("jms:queue:a");
from("jms:queue:a")
.transacted("PROPAGATION_REQUIRED")
.process(new Processor() {
@Override
public void process(Exchange arg0) throws Exception {
System.exit(1); // A
}
})
;
以下是相关的bean:
<bean id="jmsConnectionFactory" class="org.apache.activemq.ActiveMQConnectionFactory">
<property name="brokerURL" value="tcp://localhost:61616" />
</bean>
<bean id="jms" class="org.apache.camel.component.jms.JmsComponent">
<property name="transacted" value="true" />
<property name="transactionManager" ref="txManager" />
<property name="useMessageIDAsCorrelationID" value="true" />
<property name="connectionFactory" ref="jmsConnectionFactory" />
</bean>
<bean id="PROPAGATION_REQUIRED" class="org.apache.camel.spring.spi.SpringTransactionPolicy">
<property name="transactionManager" ref="txManager" />
<property name="propagationBehaviorName" value="PROPAGATION_REQUIRED" />
</bean>
当我运行它并调用Web服务时,ServiceMix将关闭。当我重新启动ServiceMix时,消息已被移动到死信队列(ActiveMQ.DLQ)。如果我在A点放置一个断点并手动关闭ServiceMix并使用任务管理器,我会看到相同的行为。
这是什么时候完成的?
答案 0 :(得分:2)
首先,您要将事务协议与非事务性协议混合使用。只要你知道你在哪里有事务性,那就没关系。
当您运行第一条路线from(WEBSERVICE_CAMEL_ENDPOINT).to("jms:queue:a");
时,Camel会尝试将您的消息从WS发送到ActiveMQ中的队列A.如果成功(在此过程中SMX不活动),ActiveMQ已将消息放入队列A上的永久磁盘。到目前为止,没有事务。
然后你会触发第二条路线。 Camel将在事务中从队列中读取消息。消息将被标记为在ActiveMQ中删除。如果完全处理路由,则事务将提交,没有任何异常。只有当Camel提交消息时,它才会从ActiveMQ中删除。在您的情况下,您正在异常地结束路由,因此,事务未被提交,因此消息不会从队列中删除。
如果事务被回滚(或者根本没有提交),ActiveMQ重新传递策略将处理消息是否被放回队列“a”或放入死信队列。
在这里阅读更多内容。 http://activemq.apache.org/message-redelivery-and-dlq-handling.html