【问题标题】:Exceptions in Spring Integration: How to log but not interceptSpring 集成中的异常:如何记录但不拦截
【发布时间】:2014-10-23 09:16:11
【问题描述】:

假设我有一个基本的 Spring 集成流程,例如:

<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 是直接通道,则整个事务将再次回滚,最终消息将最终出现在死信队列中。堆栈跟踪将再次丢失。

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

【问题讨论】:

    标签: spring exception transactions integration


    【解决方案1】:

    其实你走对了,但是你必须在登录errorHandler后手动回滚事务:

    TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
    

    仅此而已:无需保留消息并担心那里的其他副作用。

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

    【讨论】:

    • 非常感谢 Artem - 你又一次拯救了我的一天:-)
    猜你喜欢
    • 1970-01-01
    • 2016-03-14
    • 2012-09-03
    • 1970-01-01
    • 1970-01-01
    • 2014-07-19
    • 1970-01-01
    • 2011-05-13
    • 1970-01-01
    相关资源
    最近更新 更多