Spring Integration中DefaultMessageListenerContainer事务消息未回滚求助
JMS消息回滚至退避队列未生效的原因
- 核心原因是自定义ErrorChannel的配置拦截了异常传播:
你在Jms.messageDrivenChannelAdapter上指定了.errorChannel(appErrorChannel),同时又通过enrichHeaders强制设置了errorChannel头。当消息处理抛出异常时,Spring Integration会将异常封装后发送到这个自定义ErrorChannel,而非让异常重新抛给DefaultMessageListenerContainer。 DefaultMessageListenerContainer只有在监听器抛出未被捕获的异常时,才会触发事务回滚(因为setSessionTransacted(true)开启了事务)。现在异常被自定义ErrorChannel接收处理,容器判定异常已被处理,不会执行回滚逻辑,消息自然不会退回退避队列。
可选解决方案
- 移除
enrichHeaders中设置errorChannel的配置;若需保留自定义ErrorChannel,需在ErrorChannel的处理逻辑中重新抛出异常,确保容器能感知到未处理的异常以触发回滚。 - 若无需自定义ErrorChannel处理异常,直接移除所有相关errorChannel配置,让异常自然抛给容器触发回滚。
修改后的代码示例:
@Bean public DefaultMessageListenerContainer mqAdapterListenerContainer(final ConnectionFactory mqCachingConnectionFactory) { var defaultMessageListenerContainer = new DefaultMessageListenerContainer(); defaultMessageListenerContainer.setConnectionFactory(mqCachingConnectionFactory); defaultMessageListenerContainer.setSessionTransacted(true); return defaultMessageListenerContainer; } // 移除enrichHeaders的errorChannel设置 return IntegrationFlows.from(Jms.messageDrivenChannelAdapter(mqAdapterListenerContainer) .errorChannel(appErrorChannel)) // 业务处理逻辑 .handle(...) .get();
内容的提问来源于stack exchange,提问作者Rayyan
相关产品推荐
相关产品推荐

