我正在同时使用JMS和Hibernate一个独立的应用程序。
文档建议JTA已被使用,如果我想有在这两个资源交易。
然而,现在有@Transaction注解DAO方法(和HibernateTransactionManager的),这似乎已经工作。 当我打电话发()上JmsTemplate时,该消息不会立即发送,而是JMS会话致力于与Hibernate的Session的方法返回。
我不知道这是怎么可能不和JtaTransactionManager,所以我检查的源代码。 事实证明,对Hibernate都包装和JmsTemplate的注册与TransactionSynchronizationManager和JMS会话的会话时Hibernate的Session承诺将被提交。
这是什么和JTA事务之间的不同。 我可以用它来代替后者?
总之没有,2阶段提交没有和JtaTransactionManager以及XA知道数据源,你不能获得支持。
你所看到的是两个当地事务支持1相仅提交的协调。 粗略地执行这一系列事件...
- 启动JMS事务
- 阅读JMS消息
- 启动JDBC事务
- 写入到数据库
- 提交JDBC事务
- 提交/应答JMS
在JMS的事务将开始第一包覆嵌套JDBC事务,因此,如果使用Hibernate / JDBC提交失败的JMS队列将回滚。 您的JMS监听器容器应设置不 acknowledge="auto"
,而是等待Hibernate事务来发送确认之前完成。
如果你只有这两种资源,那么你将不得不考虑的问题是,当Hibernate在persiting,那么你会得到一个异常,才能确认JMS服务器成功。 不是一个大问题,因为JMS消息不丢失,你会读一遍。
然而
您必须编写了MessageListener以处理来自服务器重复的邮件
您还必须处理不能由于恶劣的数据并试图comsume它一个无限循环结束了被处理的消息。 在这种情况下,服务器可能会在消息监听配置的邮件移动到“停用消息队列”,或者你处理这个自己
其他选项,并进一步阅读
如果你的JMS服务器不支持XA(全局)事务,这是相当多的解决方案。
如果JMS服务器不支持XA事务,但是JDBC并不那么你可以使用一个和JtaTransactionManager以及使用LastResourceCommitOptimisation 。 还有,你可以像使用JOTM开源JTATransactionManagers
这JavaWorld的文章进入对你问题的空间更多的细节。
虽然这已经详细布拉德得到答复,我想解决您的问题非常具体的部分: -
我不知道这是怎么可能不和JtaTransactionManager
从春天文档: - 当检测到JTA环境中,Spring的JtaTransactionManager将用于管理事务
https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-jta.html