我正在开发一个使用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 first”在“This should last last”之前打印,但由于Thread.sleep它永远不会!我尝试对jmsListenerContainerFactory上的配置进行了一些更改,但没有任何区别。
不确定XA是否涉及此案例。实际发送的消息部分是单独的事务吗?如果是这样,问题可能是两个事务没有同步,但我不知道如何解决这个问题。
答案 0 :(得分:1)
我必须在JmsTemplate而不是JmsListenerContainerFactory上设置Session Transacted:
@Bean
public JmsTemplate jmsTemplate(ConnectionFactory connectionFactory) {
JmsTemplate jmsTemplate = new JmsTemplate(connectionFactory);
jmsTemplate.setSessionTransacted(true);
return jmsTemplate;
}