我是 JTA 的新手,目前正在深入研究其规范。我还创建了一些示例项目来更快地深入研究这个主题。我使用 IBM WebSphere 9 作为运行时。
我创建了一个由 EJB 和 MDB 组成的简单项目。这个想法是我向队列发送一些 JMS,然后 MDB 获取此消息,处理它并使用本地接口调用 EJB(MDB 和 EJB 位于同一个 EAR)。反过来,EJB 将处理传入的对象,并通过XA数据源使用 JDBC 将其写入 Oracle 数据库。
MDBonMessage()
方法有一个TransactionAttributeType.NOT_SUPPORTED
定义,正如 JTA 所说,它应该在事务上下文之外运行。
process()
从MDB调用的EJB的方法没有任何TransactionAttributes
定义,因为它来自JTA它应该有一个默认值,即TransactionAttributeType.REQUIRES_NEW
. 因此,如果我没有错,它会在被调用时启动一个新的全局 TX,还是我错了?
我还创建了一个简单的 DAO 类,它获取一个 JDBC 连接并运行语句来存储从 EJB 接收到的数据。它位于 EJB 旁边的包中的普通 Java 类中。
当我尝试运行项目时会出现问题,更具体地说,当我尝试从数据源获取连接时会出现问题。由于我使用的是 XA 数据源,因此发生XAER_PROTO异常:
[7/17/18 16:32:52:771 GMT+01:00] 000001b4 WSRdbXaResour E DSRA0304E:发生 XAException。XAException 内容和详细信息是:
XA 错误是:-6 XA 错误消息是:在不正确的上下文中调用了例程。Oracle > 错误代码是:24776 Oracle 错误消息是:内部 XA 错误
经过一段时间调查这个问题,我发现这个问题可能与 JTA 规范中的这个陈述有关:
3.4.7 本地和全球交易
...
当使用同一个连接执行本地和全局事务时,以下规则适用:
• 在连接中启动全局事务之前,必须提交(或回滚)本地事务。
• 在启动任何本地事务之前,必须将全局事务与连接解除关联。
所以我的问题是:
是一个 EJB 方法,TransactionAttributeType.REQUIRES_NEW
在 JTA 方面用 a 注释启动一个全局 TX 吗?
我的假设是否正确,即从数据源检索新的 JDBC 连接会根据 JTA 启动新的本地事务?
如果以上都是正确的,那么实际上是否可以在全局 TX 下的 EJB 中使用普通 JDBC?或者我应该只从非事务性 EJB 调用与 JDBC 相关的方法?
我应该认为上述方法是错误的吗?
我应该使用更抽象的 JTA 接口来处理数据库而不是使用“普通”的 JDBC 方法吗?如果是这样,那么哪种方式更可取?
HUWWW
相关分类