5.4. 解决 XA 总结问题
编写 XA 资源的标准 JTA 方法是明确将 XA 资源添加到当前的 javax.transaction.Transaction
对象中,即当前事务。换而言之,每次都开始新事务时,您必须明确获取 XA 资源。
5.4.1. 如何获取 XA 资源
Enlisting an XA 资源及事务涉及在 Transaction
接口上调用 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();
// 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. 关于自动清单
通过使用支持Aselisting of XA 资源的功能,而不是明确列出了 XA 资源,而是更容易且更安全。例如,在使用 JMS 和 JDBC 资源的情况下,标准技术是使用支持自动清单的 wrapper 类。
JDBC 和 JMS 访问的通用模式是:
-
应用代码要求
javax.sql.DataSource
用于 JDBC 访问,而用于 JMS 的javax.jms.ConnectionFactory
以获取 JDBC 或 JMS 连接。 - 在应用程序/OSGi 服务器中,注册这些接口的数据库或代理特定实现。
- 应用程序/OSGi 服务器将特定于数据库/代理的因素嵌套成通用池,以及列出因素。
这样,应用程序代码仍然使用 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 连接工厂。