当前位置: 首页 > 知识库问答 >
问题:

EEJava:为什么直接使用JTA?

毛宏达
2023-03-14

我试图理解JTA,并将Bitronix用作首选的事务管理器(只是为了学习和理解)。我正在看《Bitronix参考指南》中的代码,我想知道:如果我使用的是JDBC,它本身就是事务性的(连接可以提交/回滚),为什么我要编写这样的代码?!?!

现在,这段代码的要点可能是简单地演示如何在现有事务性数据存储上使用Bitronix/JTA,但我仍然不知道它提供了什么固有的好处。

然后,这个代码片段让我思考:“如果您使用的只有两个主要数据源是数据库和html" target="_blank">消息代理,并且您分别使用JDBC/JMS与它们通信,而这两个标准(JDBC/JMS)已经是事务性的,那么您为什么还需要使用JTA?!”

JTA是某种JDBC、JPA、JMS等都使用的“内部”Java EE API;只有那些想用它做些疯狂的事的百分之一的人才会被公开曝光?还是我完全忽视了JTA的理念/适用性?

我想我可以设想两个非JDBC和非JMS的用例来直接命中JTA,但由于我一开始对JTA非常模糊,我不知道这些用例是否偏离了轨道:

  • 也许你的应用程序中有一个复杂的I/O系统,并且有多个线程在磁盘上读写同一个文件。也许您会让每个线程使用一个事务来写入此文件。(是?!?不是?!?)

我想我的问题的根源是:

  • 如果我的JPA(Hibernate)和/或JDBC调用已经是事务性的,为什么我要将它们包装在JTA开始中-

提前感谢!

共有3个答案

郤立果
2023-03-14

在我看来,首先要考虑的是对TX管理器和TX系统进行装饰。

当我设计应用程序时,事务性这个词标志着我想做一些酸性的事情。我想把这个意图放在我的业务代码中,因为这应该是由业务需求驱动的。

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

此外,JTA定义了一些html" target="_blank">接口,以允许现有JTA系统和(最终是新的,最终是外来的)TX系统之间的集成。例如:GigaSpaces XAP是内存中的数据网格。它不是JMS,也不是SQL,但由于它提供了JTA集成,所以很容易对其进行研究。我们可以引用许多其他产品。。。

显然,致命的例子是支持不同系统之间的XA事务(我给Justin一个要点)。我的意思是说,即使您不使用XA事务,JTA也有价值。

徐焱
2023-03-14

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

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

开始JTA交易

为数据库中的帐户#345设置帐户余额低100美元

添加JMS消息“转账100美元到其他银行账户#987”排队

提交JTA交易

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

开始事务和提交由JTA处理。如果将其添加到队列失败,撤回也会自动回滚。

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

编辑:

JTA可以在系统部分可以正确实现XAResources的任何时候使用。通过实现它,资源可以参与分布式事务。乍一看,您提出的两个示例都可能实现XAResources

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

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

我认为准则的第一部分基本上是资源在逻辑上可以是XAResource。换句话说,ACID的概念是有意义的。第二,实现该接口是可能的,也是值得的(在尚未实现的地方)。

庞鸿骞
2023-03-14

它不仅仅是回滚打开的事务,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向我们promise它可以提交,这是XA兼容的一部分)。

JTA的真正伟大之处在于,您可以轻松实现自己的自定义XAResources并将其绑定到这个伟大的框架中!

更新

因此,要回答您关于何时实施自定义事务的问题,您可以问自己以下问题:

  1. 您的自定义状态或文件是否不能成为事务范围中的最终代码块
  2. 当外部系统(如DB或JMS)出现故障时,是否需要恢复自定义状态/文件
  3. 是一个简单的getRollbackOnly()

如果答案都是1,2

但是,如果您的代码是一个框架或库,它将由Java EE空间中的业务逻辑登记,那么您可能需要为它实现一个XAResource!

 类似资料:
  • 问题内容: 为什么这个简单的测试用例用SQLAlchemy插入100,000行比直接使用sqlite3驱动程序慢25倍?我在现实世界的应用程序中看到过类似的减速情况。难道我做错了什么? 我尝试了许多变体(请参阅http://pastebin.com/zCmzDraU) 问题答案: 将更改同步到数据库时,SQLAlchemy ORM使用工作单元模式。这种模式远远超出了简单的数据“插入”。它包括使用属

  • 我使用dropwizard制作了一个非常传统的文件上传方法。 所以我在资源中有一个这样的方法 里面没有什么特别的,它只是保存到一个路径,使用java.nio库,就像这样 它只是不会上传excel文件。我在其他地方读到excel文件和它们的底层类型受到怀疑。请问我需要做什么?

  • 问题内容: 与仅返回自己的Spring Async相比,使用Spring Async有 什么优势? 问题答案: 您的应用程序由容器管理。由于不建议您自己生成,因此可以让容器注入Managed 。

  • 问题内容: 我看到许多人试图将Android设备直接连接到SQL Server或MySql这样的数据库中,答案始终是相同的:使用Web服务。为什么不直接将Android设备与数据库连接?我的Android应用程序使用的是本地网络。 问题答案: 有很多原因。 安全性-如果用户具有直接访问权限,则他们可以从您的数据库中获取任何信息。另外,他们将在您的数据库中输入密码。因此,如果您使用的SQL Serv

  • 问题内容: 谁能解释我为什么不应该使用在窗口内直接绘制的方法,而应该在内部使用方法? 提前致谢。 问题答案: 三大原因… 顶层容器不是双缓冲的,在重新绘制框架时会导致闪烁,是的,您可以实现自己的双缓冲,但是… 在框架内绘画不会考虑框架边框,这意味着可以在框架边框下绘画。边框也取决于平台/外观,这意味着尺寸会发生变化 对于Swing窗口,窗口上已经存在一些组件,这意味着它们在大多数情况下都被覆盖(或

  • 定义在components文件下的子组件 然后在views文件夹中,直接使用,并没有import引入,也没有注册在components中为什么可以直接使用 ?