5.4. 解决 XA enlistment 问题
要列出 XA 资源的标准 JTA 方法是将 XA 资源明确添加到当前 javax.transaction.Transaction
对象,它代表当前的事务。换句话说,每次新事务启动时,您必须明确列出 XA 资源。
5.4.1. 如何列出 XA 资源
使用 事务
列出 XA 资源涉及在事务中调用 enlistResource ()
方法。例如,给定一个 TransactionManager
对象和 XAResource
对象,您可以按如下方式列出 XAResource
对象:
// Java import javax.transaction.Transaction; import javax.transaction.TransactionManager; import javax.transaction.xa.XAResource; ... // Given: // 'tm' of type TransactionManager // 'xaResource' of type XAResource // Start the transaction tm.begin(); Transaction transaction = tm.getTransaction(); transaction.enlistResource(xaResource); // Do some work... ... // End the transaction tm.commit();
列出资源的技巧方面是必须在 每个新事务上列出 资源,在开始使用资源前必须列出该资源。如果您明确列出资源,则可能会出现容易出错的代码,这些代码使用 enlistResource ()
调用。此外,有时很难在正确的位置调用 enlistResource ()
,例如,如果您使用一个隐藏了一些事务详细信息的框架时,会出现这种情况。
5.4.2. 关于自动加入
使用支持 XA 资源的自动连接的功能,而不是明确列出 XA 资源。例如,在使用 JMS 和 JDBC 资源的情况下,标准技术是使用支持自动加入的打包程序类。
JDBC 和 JMS 访问的常见模式是:
-
应用程序代码需要
javax.sql.DataSource
for JDBC access 和javax.jms.ConnectionFactory
for JMS 获取 JDBC 或 JMS 连接。 - 在应用程序/OSGi 服务器中,会注册这些接口的数据库或代理特定实现。
- application/OSGi 服务器将 database/broker 特定工厂嵌套成通用、池、清单工厂。
这样,应用程序代码仍然使用 javax.sql.DataSource
和 javax.jms.ConnectionFactory
,但在访问它们时内部存在额外的功能,这通常涉及:
- 连接池 - 而不是在每次创建新连接时都创建新的连接,而是使用重新初始化的 连接池。池的另一个 方面可能是连接的定期验证。
-
JTA enlistment - 在返回
java.sql.Connection
(JDBC)或javax.jms.Connection
(JMS)的实例之前,如果实际连接对象是 true XA 资源,则会注册实际连接对象。注册会在 JTA 事务中发生(如果可用)。
通过自动协助,应用程序代码不必更改。
有关 JDBC 数据源和 JMS 连接工厂的池和配套打包程序的更多信息,请参阅 第 6 章 使用 JDBC 数据源 和 第 7 章 使用 JMS 连接工厂。