You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Boot集成ActiveMQ时@JmsListener接收自身发送消息被阻塞问题咨询

问题原因

默认配置下,ActiveMQ 5 对 @JmsListener 标注的消费方法会自动开启本地事务,且 JmsTemplate 默认复用当前线程绑定的消费会话:

  • 你在 onIn 方法中发送的 out 队列消息,会被纳入当前消费会话的事务中
  • 事务内的消息虽然已经同步到 Broker 端,会在管控台展示为已到达,但会被标记为未提交状态,对所有普通消费者不可见;只有当整个 onIn 方法执行完成、消费事务提交后,out 队列的消息才会变为可消费状态,被监听器或 JmsTemplate 拉取
  • 为 onIn 添加 @Async 注解后,方法会运行在独立异步线程中,发送消息时会创建全新的 JMS 会话,不受原消费事务约束,消息发送后会立即提交,因此可以被马上消费。
无需 @Async 的解决方案

方案1:关闭消费端事务(无事务需求推荐)

如果你的业务不需要消费失败自动回滚重试的事务保障,直接修改配置关闭监听器的事务开关即可:
在 application.properties 中添加配置:

spring.jms.listener.session-transacted=false
spring.jms.listener.acknowledge-mode=auto

修改后消费方法不再开启事务,消息发送后立即生效,无需等待方法执行完成。

方案2:独立配置发送用非事务JmsTemplate(需保留消费事务时使用)

如果必须保留消费端的事务能力,可以单独定义一个非事务的 JmsTemplate 用于发送响应消息,避免和消费会话绑定:

import javax.jms.Session;
import org.springframework.context.annotation.Bean;
import org.springframework.jms.core.JmsTemplate;
import javax.jms.ConnectionFactory; // SpringBoot 3.x及以上版本改为jakarta.jms.ConnectionFactory

@Bean
public JmsTemplate nonTransactedJmsTemplate(ConnectionFactory connectionFactory) {
    JmsTemplate jmsTemplate = new JmsTemplate(connectionFactory);
    jmsTemplate.setSessionTransacted(false);
    jmsTemplate.setSessionAcknowledgeMode(Session.AUTO_ACKNOWLEDGE);
    return jmsTemplate;
}

在业务代码中注入这个自定义的 JmsTemplate 发送 out 队列消息即可,发送的消息不会被纳入消费事务,发完即可被消费者正常接收。

内容的提问来源于stack exchange,提问作者Mark Schäfer

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.06 21:57:04