仅在JPA事务提交后发送JMS消息

仅在JPA事务提交后发送JMS消息,jms,activemq,spring-jms,xa,Jms,Activemq,Spring Jms,Xa,我正在从事一个利用Spring的JmsTemplate、ActiveMQ和Hibernate的项目。我在一个事务中包装了一个方法,它通过JmsTemplate发送消息,做更多的工作,然后返回,这样事务就可以提交了。我希望消息只在事务提交后发送,即JmsListener只应在上述方法返回后触发 以以下发送方和接收方为例: @Service @Transactional public class TestService{ @Autowired private JmsTemplate 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.");
  }
}
我想在“This should run last”之前先打印文本“This should run first”,但因为Thread.sleep,它永远不会打印!我尝试了对jmsListenerContainerFactory上的配置进行一些更改,但没有任何改变


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

我必须在JmsTemplate而不是JmsListenerContainerFactory上设置会话事务:

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

我也有类似的情况。只是想知道在sleep()之后是否会发生异常,然后jms消息是否会回滚?