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

在@JmsListener中使用JmsTemplate发送JMS消息遇接收异常问题

问题:@JmsListener方法内发送JMS消息超时不投递

我在标注@JmsListener的方法内部发送JMS消息,代码示例如下:

@Autowired
private JmsTemplate jmsTemplate;

@JmsListener(destination = "myQueue1")
public void receiveMessage(@Payload ObjectMessage message) {
     someWork1(); //takes few milliseconds

     jmsTemplate.send("myQueue2");

     someWork2(); //takes a minute
}

当前场景下,当该方法整体执行时长为1分钟时,myQueue2的消费者无法接收消息;若someWork2()仅耗时10-15秒,则myQueue2的消费者可成功接收消息。

当前TTL配置为:

spring.jms.template.time-to-live=36000

原因分析

首先明确:spring.jms.template.time-to-live的单位是毫秒,36000即36秒。问题核心在于事务上下文的影响:

默认情况下,@JmsListener的方法运行在事务中:

  • 调用jmsTemplate.send()时,消息并没有立即投递到myQueue2,而是暂存在当前事务的资源里
  • 只有当整个receiveMessage()方法执行完毕、事务提交后,消息才会真正被发送到队列
  • 如果someWork2()耗时1分钟,从发送消息到事务提交的间隔会超过36秒,导致消息过期,自然不会被消费者接收

解决方案

1. 调整消息TTL(最简单方案)

如果业务允许,直接把TTL调大到超过方法的最长执行时间:

spring.jms.template.time-to-live=60000 # 设置为60秒,覆盖1分钟的执行时长

2. 开启新事务发送消息(推荐)

给发送myQueue2的逻辑单独开启新事务,让消息立即提交,不受当前监听器事务的影响。可以用@Transactional(Propagation.REQUIRES_NEW):

先定义独立的消息发送服务:

@Service
public class JmsSenderService {

    @Autowired
    private JmsTemplate jmsTemplate;

    @Transactional(propagation = Propagation.REQUIRES_NEW)
    public void sendToMyQueue2() {
        jmsTemplate.send("myQueue2", session -> {
            // 这里构造你的消息,示例为文本消息
            return session.createTextMessage("message content");
        });
    }
}

然后在监听器中调用这个服务:

@Autowired
private JmsSenderService jmsSenderService;

@JmsListener(destination = "myQueue1")
public void receiveMessage(@Payload ObjectMessage message) {
     someWork1();

     jmsSenderService.sendToMyQueue2(); // 新事务提交后,消息立即投递

     someWork2();
}

3. 关闭监听器事务(谨慎使用)

如果业务不需要事务一致性,可以关闭@JmsListener的事务:

spring.jms.listener.transaction.enabled=false
spring.jms.listener.acknowledge-mode=auto # 根据需求选auto或client

⚠️ 注意:这种方式会丢失事务保障,比如someWork2()执行失败时,myQueue1的消息已经被确认,无法回滚,仅适用于无事务要求的场景。


内容的提问来源于stack exchange,提问作者Hasn A

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 00:42:25