【问题标题】:How to use a JTA transaction with two databases?如何在两个数据库中使用 JTA 事务?
【发布时间】:2014-03-12 13:17:29
【问题描述】:
App1 使用 App2 公开的一些客户端 api 与 App2(EJB 应用程序)交互。在 Jboss 中使用 CMT 管理的 JTA 事务。我们正在使用 JNDI 查找从 App2(Jboss)获取 UserTransaction。
- App1 调用 App2 以使用
UserTransaction's begin() and commit() 将数据插入 DS2。
- App1 使用 Hibernate JPA 调用 DS1,以使用 JPATransaction Manager 将数据插入 DS1。
- 是否可以在单个事务中包装两个数据库操作(分布式事务)
PFB 描述需求的图片
【问题讨论】:
标签:
java
spring
jboss5.x
jta
distributed-transactions
【解决方案1】:
为此,有必要实现您自己的事务资源,能够加入正在进行的 JTA 事务。请参阅此answer 以及一些指南,了解如何完成此操作的一种方法是查看数据库或 JMS 资源的 XA 驱动程序代码,并以此为基础。
这并非易事,也是一个非常罕见的用例,通常在实践中通过采用替代设计来解决。一种方法是将 App2 中的必要代码提取到一个 jar 库中,并在 Tomcat 中使用它,并在 Tomcat 中使用连接到两个 XA JTA 数据源的 Atomikos 之类的 JTA 事务管理器。
另一种方法是将SQL语句刷新到数据库到tomcat中,看看是否有效,然后再向JBoss发送同步调用,如果JBoss中的事务通过则返回结果。
取决于 tomcat 中的提交/回滚。这并不能保证 100% 的时间(网络故障等)都能正常工作,但可能是可以接受的,具体取决于系统所做的事情以及失败事务的业务后果。
还有一种方法是使操作在 JBoss 端可恢复,并公开一个由 tomcat 使用的补偿服务,以防检测到错误。为此并制作两台服务器 JBoss,您可以利用 JBoss Narayana 引擎,另请参阅 answer。
哪种方式更好取决于用例,但实现自己的 XA 事务服务是一项艰巨的任务,我会更简单地更改设计。很少有项目这样做的原因是它很复杂并且有更简单的替代方案。
【解决方案2】:
Tomcat 是一个网络服务器,所以它不支持全局事务。
JBoss 是一个应用服务器,所以它支持全局事务。
如果必须将两者结合起来,则必须使用 JOTM 或 ATOMIKOS,它们充当 Trasaction Manager 并提交或回滚。