我通过Atomikos和JMS使用Spring Integration和JTA支持绑定到不同的Webshpere MQ和Oracle数据库 .
对于其他人而言,它似乎与_2732233中的线程相同,但它根本不是 .
流程如下:
-
message-driven-channel-adapter接收事务内的消息
-
一些转变
-
ServiceActivator具有更深层次的业务逻辑
-
数据库更新
对于一个szenario来说,一切都很顺利:
如果在ServiceActivator中发生未经检查的异常(可能是由于不应该存在的不一致数据),则会在ErrorHandler(通过ErrorChannel)中重新抛出并处理该消息 . 在某些情况下,应该将orgininal传入消息发送到DeadLetter队列(Webshere MQ) . 这是通过出站通道适配器完成的 .
见封闭配置:
<jms:message-driven-channel-adapter id="midxMessageDrivenAdapter"
channel="midxReplyChannel"
acknowledge="auto"
transaction-manager="transactionManager"
connection-factory="connectionFactory"
concurrent-consumers="1"
error-channel="errorChannel"
max-concurrent-consumers="${cmab.integration.midx.max.consumer}"
idle-task-execution-limit="${cmab.integration.midx.idleTaskExecutionLimit}"
receive-timeout="${cmab.integration.midx.receiveTimeout}"
destination="midxReplyQueue"/>
................
<int:service-activator input-channel="midxReplyProcessChannel" ref="processMidxReplyDbWriter" />
<int:service-activator input-channel="errorChannel" ref="inputErrorHandler" />
<jms:outbound-channel-adapter id="deadLetterOutboundChannelAdapter"
channel="errorDlChannel" destination="deadLetterQueue"
delivery-persistent="true" connection-factory="nonXAConnectionFactory"/>
Some important hints: 消息驱动通道适配器:
-
connectionFactory是一个MQXAQueueConnectionFactory,它与AtomikosConnectionFactoryBean相连
-
transaction-manager是Spring JtaTransactionManager
出站通道适配器:
connection-factory是一个非XAConnectionFactory .
CachingConnectionFactory cachingConnectionFactory = new CachingConnectionFactory();
MQQueueConnectionFactory mqQueueConnectionFactory = new MQQueueConnectionFactory();
.....
cachingConnectionFactory.setTargetConnectionFactory(mqQueueConnectionFactory);
return cachingConnectionFactory;
And now the error which I observed:
虽然我在ErrorHandler中处理了未经检查的异常(ref = "inputErrorHandler";将消息发送到DeadLetter-Queue),但是启动了回滚,并且消息驱动通道适配器一次又一次地接收消息 .
实际上,消息是通过出站通道适配器传递给DeadLetterQueue的事实 . 目标(deadLetterQueue)包含失败的消息 .
问题:我做错了什么?虽然我在ErrorHandler中处理了异常,但回滚失败的原始传入消息 .
任何帮助真的很感激 . 提前谢谢了 .
1 回答
关于我的评论,请参阅我的InputErrorHandler的代码:
正如我所提到的,“business”ServiceActivator会抛出一个未经检查的异常,因此在这种情况下,ELSE-Statements正在调用 . 在其中,我使用MessagBuilder构建一个Message并将其发送到errorDlChannel(s . 在出站通道适配器上方!) .
就这样 . 对于这种情况,这是最后一个陈述 . 我的ErrorHandler的main方法中没有任何其他内容 . 没有重新抛出或其他东西 .
所以这就是我困惑的原因 . 对我来说,异常是通过将它发送到errorDlChannel(outbound-channel-adapter - > DeadLetterQueue)来处理的 .
我在DeadLetter Queue上看到了这条消息,但仍然发生了jta回滚......而IMO这不应该是蜜蜂 .