Java EE:为什么直接使用JTA?

时间:2012-06-29 17:17:29

标签: java-ee jta

我正在尝试理解JTA,并且正在使用Bitronix作为首选的事务管理器(仅为了学习和理解)。我正在查看Bitronix reference guide here中的代码,我想知道自己:如果我正在使用JDBC,它本身就是事务性的(Connection可以提交/回滚),为什么我会想写这样的代码吗?!?!

现在,该代码片段的目的可能只是演示如何在现有的事务数据存储上使用Bitronix / JTA,但我仍然没有获得它提供的固有优势。

然后,这段代码让我想到:“如果您使用的唯一两个主要数据源是数据库和消息代理,并且您使用JDBC / JMS分别与它们进行通信,以及这两个标准(JDBC / JMS) )已经是事务性的,那为什么你需要使用JTA?!?!

JTA是一种JDBC,JPA,JMS等都使用的“内部”Java EE API;只有1%的人想要做一些疯狂的事情才公开曝光?或者我完全错过了JTA的想法/适用性?

我想我可以设想两个非JDBC和非JMS用例直接命中JTA,但是因为我首先在JTA上如此模糊,所以我不知道这些情况是否偏离轨道:

  • 也许您的应用程序中有一个复杂的I / O系统,并且有多个线程从磁盘上的同一文件读取/写入。也许你会让每个线程使用一个事务来写入这个文件。 (是吗?!?不?!?)
  • 也许你有一个表示系统状态的状态机POJO,多个线程可以修改机器。也许你会让每个线程使用一个事务来改变机器的状态。 (是吗?!?不?!?)

我想我问题的根源是:

  • 如果我的JPA(Hibernate)和/或JDBC调用已经是事务性的,为什么我要将它们包装在JTA begin-> commit / rollback block中呢?同样适用于JMS和消息传递系统。
  • 在JPA / JDBC / JMS之外,使用JTA处理一系列操作有哪些用例?

提前致谢!

3 个答案:

答案 0 :(得分:25)

它不仅仅是回滚开放事务,JTA提供了一个XAResource接口,供应商可以实现,您的JDBC驱动程序和JMS提供程序已经实现了这一点,您可以实现自己的。这是基于开放标准,可能值得一读。

现在我们为什么要这个?

在灾难中考虑马修斯的例子:

Begin DB Transaction

Set AccountBalance $100 lower for Account #345 in database

Add JMS Message "Transfer $100 to OtherBank Account #987" to queue

*** DB power is unplugged while committing DB Transaction ***

不幸的是,JMS消息已经转移到另一家银行,这对分布式事务来说是一个非常现实的问题。

使用XA,这就是场景的演绎方式:

DB Transation starts XA Transaction

Set AccountBalance $100 lower for Account #345 in database

JMS Connection joins XA Transaction 

Add JMS Message "Transfer $100 to OtherBank Account #987" to queue

Everything went okay and JTA context is ready to commit.

DB and JMS both agree that they are capable of commiting.

JTA instructs DB and JMS to commit.

All members of the transaction commit.

现在您可能会问,如果在DB的最终提交期间拔出电源插头会发生什么。那么JMS队列将提交,但是XA事务将保持打开,直到DB再次可用,此时它将再次指示DB提交(DB承诺我们可以提交,这是符合XA的一部分) )。

JTA真正的优点是你可以轻松实现自己的自定义XAResource并与这个伟大的框架结合!

<强>更新

因此,要回答有关何时实施自定义交易的问题,您可以问自己以下内容:

  1. 您的自定义状态或文件UNABLE是否是事务范围中的最终代码块?
  2. 您是否需要在外部系统(即DB或JMS)故障时恢复自定义状态/文件?
  3. 是一个简单的getRollbackOnly()&amp;外部系统的setRollbackOnly(),加上补偿处理(即显式恢复自定义状态/文件),自定义代码不足?
  4. 如果对1,2和2的回答都是如此3是YES然后你可能想要一个自定义的XAResource,否则我认为它可能有点过分。

    但是,如果您的代码是将在Java EE空间中由业务逻辑登记的框架或库,您可能希望为它实现XAResource!

答案 1 :(得分:3)

您可以拥有一个事务,该事务涵盖数据库和消息服务。如果没有JTA,我不知道有什么方法可以做到。

简单的概念示例。确切的代码并不重要:

  

开始JTA交易

     

为数据库

中的帐户#345设置AccountBalance $ 100      

添加JMS消息“将$ 100转移到OtherBank帐户#987”到队列

     

提交JTA交易

OtherBank是一个独立的银行,我们假设您通过JMS与它进行通信。

Begin Transaction和Commit由JTA处理。如果将其添加到队列失败,撤销也会自动回滚。

现实生活并不那么简单,但这应该会给你一个想法。

编辑:

只要系统的一部分能够正确实现XAResource,就可以使用JTA。通过实现它,资源可以参与分布式事务。乍一看,您提出的两个示例都可能实现XAResource

“您应用中的一个复杂的I / O系统,并且有多个线程从磁盘上的同一文件读取/写入。” - 如果你考虑一下,这听起来像是一个数据库。

“也许你有一个表示系统状态的状态机POJO,多个线程可以修改机器。” - 如果可以充分隔离变化,这肯定是候选人。

我认为标题的第一部分基本上是资源逻辑可以XAResource。换句话说,ACID的概念是有意义的。第二,可能并且值得努力实现该接口(它尚未实现)。

答案 2 :(得分:0)

在我看来,首先要考虑的是解析TX管理器和TX系统。

当我设计我的应用程序时,Transactional这个词标记了我做某事ACID的意图。我想将此意图放在我的业务代码中,因为这应该由业务需求驱动。

我希望一些神奇的东西(我现实生活中的容器)能正确编织我的tx意图,这取决于底层的TX系统(数据库,jms经纪人等)

此外,JTA定义了一些接口,以允许现有JTA系统和(最终新的,最终奇特的)TX系统之间的集成。例如:GigaSpaces XAP是内存中的数据网格。它不是JMS,不是SQL,但很容易将其作为it provides a JTA integration。我们可以引用很多其他产品......

显然,杀手级的例子是支持不同系统之间的XA事务(我给Justin一点)。我的观点是,即使你不使用XA交易,JTA也有价值。