Spring Integration中的异常:如何记录但不拦截

时间:2014-08-29 10:59:15

标签: spring exception transactions integration

假设我有一个基本的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是一个直接通道,整个事务将再次回滚,最终消息将以死信队列结束。再一次,堆栈跟踪将丢失。

处理这些问题的最佳做法是什么?

1 个答案:

答案 0 :(得分:2)

实际上你走的是正确的,但是你必须在你的errorHandler登录后手动回滚交易:

TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();

这就是全部:不需要坚持留言并担心其他副作用。

当然,您的myErrorChannel必须是direct频道才能在同一交易线程中进行日志记录和回滚。