jms - 仅在 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。消息的实际发送是单独交易的一部分吗?如果是这样,问题可能是两个事务没有同步,但我不知道如何解决。
解决方案
我必须在 JmsTemplate 而不是 JmsListenerContainerFactory 上设置 Session Transacted:
@Bean
public JmsTemplate jmsTemplate(ConnectionFactory connectionFactory) {
JmsTemplate jmsTemplate = new JmsTemplate(connectionFactory);
jmsTemplate.setSessionTransacted(true);
return jmsTemplate;
}
推荐阅读
- reactjs - `instance` 变量是否会导致性能不佳?
- c# - 无法在 Azure 部署中心选择任何组织存储库
- delphi - Delphi XE4 会安装在 Windows 10 上吗?使用 XE4 创建的应用程序会在 Windows 10 上运行吗?
- javascript - 如何从纯 JavaScript (jQuery-Plugin) 访问 AngularJS 服务方法
- mongodb - mongo-connector 到具有私有 IP 的远程 mongo 公共 IP
- c# - 即使在关闭应用程序后保存应用程序数据的最简单方法是什么
- javascript - asp-fallback-test-property 与 asp-fallback-test 之间的区别
- python - sympy 设置隐式绘图范围(实体截断)
- java - 将生成的类捆绑到一个 jar 中并将其添加到构建类路径中
- php - php数组根据值删除n个项目