假设我有一个基本的 Spring 集成流程,例如:
<jms:inbound-channel-adapter>
<poller>
<transactional/>
</poller>
</jms:inbound-channel-adapter>
<some:outbound-channel-adapter/>
如果出站适配器抛出异常,则整个事务将回滚。
如果入站消息子系统支持,消息将被重新传递多次,直到最终被发布到死信队列中。这很好 - 只是异常本身丢失了,从诊断的角度来看这是非常烦人的。
如果我使用错误 channel 配置入站适配器,例如:
<jms:inbound-channel-adapter>
<poller error-channel="myErrorChannel" >
<transactional/>
</poller>
</jms:inbound-channel-adapter>
<some:outbound-channel-adapter/>
然后异常被捕获并成为 myErrorChannel 上消息有效负载的一部分。然后,我可以读取该消息并将异常的堆栈跟踪保留到日志中以用于诊断目的 - 但要付出一定的代价 - 入站适配器上的事务不再回滚并且原始消息会丢失 - 除非我也保存它作为错误处理的一部分。
但是如果保留异常或原始消息也失败怎么办?我想如果 myErrorChannel 是直接 channel ,整个事务将再次回滚,最终消息将出现在死信队列中。堆栈跟踪将再次丢失。
处理这些问题的最佳实践是什么?
最佳答案
实际上你的做法是正确的,但是在将事务记录到 errorHandler
中后,你必须手动回滚事务:
TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
仅此而已:无需保留消息并担心其他副作用。
当然,您的 myErrorChannel
必须是direct
channel 才能在同一事务线程中进行日志记录和回滚。
关于spring - Spring集成异常: How to log but not intercept,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25566934/