繁体   English   中英

Spring同步Hibernate和JMS事务

[英]Spring synchronising Hibernate and JMS transactions

我正在使用一个同时使用JMS和Hibernate的应用程序。

文档建议如果我想在两个资源之间进行交易,则必须使用JTA。

但是,现在使用@Transaction带注释的DAO方法(和HibernateTransactionManager),这似乎已经起作用了。 当我在JmsTemplate上调用send()时,消息不会立即发送,而是在方法返回时使用Hibernate会话提交JMS会话。

如果没有JtaTransactionManager,我不知道这是怎么可能的,所以我检查了源代码。 事实证明,Hibernate和JmsTemplate的包装器都会使用TransactionSynchronizationManager注册会话,并且在Hibernate会话提交时将提交JMS会话。

这和JTA交易有什么不同。 我可以用它来取代后者吗?

简而言之,如果没有JTATransactionManager和XA感知数据源,您将无法获得对两阶段提交的支持。

您目击的是仅支持单阶段提交的两个本地事务的协调。 大致执行这一系列事件......

  1. 启动JMS事务
  2. 读取JMS消息
  3. 启动JDBC事务
  4. 写入数据库
  5. 提交JDBC事务
  6. 提交/确认JMS

首先将包装嵌套的JDBC事务启动JMS事务,以便在Hibernate / JDBC提交失败时回滚JMS队列。 您的JMS侦听器容器应设置为 acknowledge="auto" ,而是在发送确认之前等待Hibernate事务完成。

如果您只有这两个资源,那么您必须考虑的问题是,当Hibernate成功持久化时,您会在确认JMS服务器之前获得异常。 这不是一个大问题,因为JMS消息不会丢失,您将再次阅读它。

然而

  1. 您必须编写MessageListener来处理来自服务器的重复消息

  2. 您还必须处理由于数据不良而无法处理的消息,并最终导致无限循环尝试使用它。 在这种情况下,服务器可能配置为将消息移动到“死消息队列”,或者您自己在MessageListener中处理此消息

其他选项和进一步阅读

如果您的JMS服务器不支持XA(全局)事务,那么这几乎是您唯一的解决方案。

如果JMS服务器确实支持XA事务但JDBC没有,那么您可以使用JTATransactionManager并使用LastResourceCommitOptimisation 有像JOTM一样可以使用的开源JTATransactionManagers

这篇JavaWorld文章详细介绍了您的问题空间。

虽然Brad已经详细解答了这个问题,但我想解决一下你查询的一个非常具体的部分: -

如果没有JtaTransactionManager,我不知道这是怎么回事

从spring文档: - 当检测到JTA环境时,Spring的JtaTransactionManager将用于管理事务

https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-jta.html

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM