假设我有一个基本的Spring Integration流程,如:
<jms:inbound-channel-adapter>
<poller>
<transactional/>
</poller>
</jms:inbound-channel-adapter>
<some:outbound-channel-adapter/>
如果出站适配器抛出异常,则回滚整个事务。
如果入站消息子系统支持该消息,则该消息将被重新传递多次,直到最终将其发布在死信队列上。这很好 - 除了异常本身丢失,从诊断的角度来看非常烦人。
如果我使用错误通道配置入站适配器,如:
<jms:inbound-channel-adapter>
<poller error-channel="myErrorChannel" >
<transactional/>
</poller>
</jms:inbound-channel-adapter>
<some:outbound-channel-adapter/>
然后捕获异常并成为myErrorChannel上消息的有效负载的一部分。然后,我可以读取消息并将异常的堆栈跟踪持久保存到日志中以进行诊断 - 但需要付出代价 - 入站适配器上的事务不再回滚并且原始消息丢失 - 除非我保存它作为错误处理的一部分。
但是如果持久化异常或原始消息也会失败呢?我想如果myErrorChannel是一个直接通道,整个事务将再次回滚,最终消息将以死信队列结束。再一次,堆栈跟踪将丢失。
处理这些问题的最佳做法是什么?
答案 0 :(得分:2)
实际上你走的是正确的,但是你必须在你的errorHandler
登录后手动回滚交易:
TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
这就是全部:不需要坚持留言并担心其他副作用。
当然,您的myErrorChannel
必须是direct
频道才能在同一交易线程中进行日志记录和回滚。