首页 > 解决方案 > 仅在 JPA 事务提交后才发送 JMS 消息

问题描述

我正在开发一个使用 Spring 的 JmsTemplate、ActiveMQ 和 Hibernate 的项目。我有一个包装在事务中的方法,它通过 JmsTemplate 发送消息,做更多的工作然后返回,以便事务可以提交。我希望仅在事务提交后才发送消息,即 JmsListener 应仅在上述方法返回时触发。

以下面的发送者和接收者为例:

@Service
@Transactional
public class TestService{

  @Autowired
  private JmsTemplate jmsTemplate;

  public void test() throws InterruptedException {
    jmsTemplate.convertAndSend("test_queue", "Test");
    Thread.sleep(1000L);
    System.out.println("This should run first");
  }
}

@Service
@Transactional
public class Listener {

  @JmsListener(destination = "test_queue", containerFactory = "jmsListenerContainerFactory")
  public void onMessage() {
    System.out.println("This should run last.");
  }
}

我希望在“这应该最后运行”之前打印文本“这应该首先运行”,但是由于 Thread.sleep 它永远不会!我尝试了对 jmsListenerContainerFactory 上的配置进行了一些更改,但没有任何区别。

不确定本案是否涉及 XA。消息的实际发送是单独交易的一部分吗?如果是这样,问题可能是两个事务没有同步,但我不知道如何解决。

标签: jmsactivemqspring-jmsxa

解决方案


我必须在 JmsTemplate 而不是 JmsListenerContainerFactory 上设置 Session Transacted:

@Bean
public JmsTemplate jmsTemplate(ConnectionFactory connectionFactory) {
    JmsTemplate jmsTemplate = new JmsTemplate(connectionFactory);
    jmsTemplate.setSessionTransacted(true);
    return jmsTemplate;
}

推荐阅读