spring - Spring集成异常: How to log but not intercept

标签 spring exception transactions integration

假设我有一个基本的 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/

相关文章:

java - TransactionManager read-only=true 不适用于 mysql ReplicationDriver

java - 如何从另一台服务器获取请求url到spring mvc Controller 中

spring - Maven:如何包含具有特定构建配置文件的依赖项?

java.util.ConcurrentModificationException 谁能给我解释一下这个的逻辑原因

c# - Entity Framework 6 中显式数据库事务的意义是什么?

mysql - 插入多行时 commit() 的最佳实践

java - 没有足够的内存用于 Spring Boot(从 1Gb heroku dyno 开始)

android - 即使 Activity 存在,ActivityNotFound

java - 如果未找到对象,则在 getter 方法中返回值

php - 为什么每一行提交交易这么慢?