何时配置XADataSource
如第二节所述,您的代码将始终使用DataSource
接口(可能使用XADataSource
)。如果问题是何时应使用XADataSource
(例如在应用程序服务器中配置它),则答案很简单:
如果您需要进行分布式事务,则使用XADataSource
:即确保跨多个资源(例如不同数据库)成功或失败的事务。
如果您不需要分布式事务,那么仍然可以配置XADataSource
,但这可能会产生一些开销,例如未使用的额外对象(例如XAResource
)以及数据源执行的“簿记”方面。不过,这种开销可能是可以忽略不计的。
某些数据源(例如在您的问题中提到的Tomcat池)可以使用DataSource
或XADataSource
作为工厂来创建连接(根据JDBC规范,ConnectionPoolDataSource
也应作为工厂可用,但看起来Tomcat忽略了该选项)。这并不改变您决定使用什么的方式:
不需要分布式事务:
程序--使用--> Tomcat连接池DataSource
--使用--> JDBC驱动程序DataSource
需要分布式事务:
程序--使用--> Tomcat连接池DataSource
--使用--> JDBC驱动程序XADataSource
在两种情况下,连接池都由Tomcat连接池DataSource
提供,而不是JDBC驱动程序(XA)DataSource
提供。正确的*XADataSource
实现不会实现连接池:这将是使用XADataSource
作为其工厂的DataSource
实现的(可选)责任。因此,这不是选择(或不选择)XADataSource
的原因。
您的问题可能源于混淆的术语,即XADataSource
创建扩展PooledConnection
的XAConnection
。名称PooledConnection
并不意味着它来自连接池,而是意味着在创建后,这些可以保存在连接池中(该连接池将位于调用XADataSource.getXAConnection
的DataSource
内部)。
DataSource
和XADataSource
的职责
在JDBC中,
DataSource
的责任是创建可以被你的应用程序使用的连接。这意味着它可以是一个非常基本的实现,仅仅是直接使用
DriverManager
,但也可以是提供了连接池和分布式事务支持的实现。
思路是你可以将一个实现替换为另一个实现,而你的代码将不受影响。
因此,消耗连接的代码应始终使用
javax.sql.DataSource
实现。
javax.sql.XADataSource
(以及
javax.sql.ConnectionPoolDataSource
)旨在由提供高级功能(如连接池和/或分布式事务)的
javax.sql.DataSource
实现使用。不应直接在你自己的程序中使用它们。正如你所链接的教程所说:
同样地,当DataSource
实现与XADataSource
类集成时,它生成的所有连接都将自动成为可以在分布式事务中使用的连接。
换句话说,
DataSource
是你用来获取连接的API,而
XADataSource
是由提供分布式事务支持的数据源库使用的。它获取
XAConnection
,在分布式事务管理器中注册它,然后给你从
XAConnection.getConnection()
获取的逻辑连接。
这也在JDBC 4.2规范第12.1节中进行了描述:
分布式事务需要提供以下基础架构:
- 事务管理器-控制事务边界并管理两阶段提交协议。通常将是JTA的实现。
- JDBC驱动程序,它们实现
XADataSource
、XAConnection
和 XAResource
接口。这些在下一节中描述。
- 应用程序可见的
DataSource
实现,以“覆盖”每个XADataSource
对象,并与事务管理器交互。该DataSource
实现通常由应用服务器提供。
- 资源管理器(s)来管理底层数据。在JDBC API的上下文中,资源管理器是一个DBMS服务器。术语“资源管理器”是从JTA借来的,以强调使用JDBC API进行分布式事务遵循该文档中指定的架构。
简而言之:你--使用-->
DataSource
--(可能)使用-->
XADataSource
另外注意:在各种JDBC实现中,历史上存在着有关职责的某些混淆,在某些情况下,连接池同时实现了所有三个接口。
XADataSource
用于two-phase
提交以同步不同应用程序实例使用的数据。我只记得在使用Oracle ATG Commerce
时有这个区别,它使用JTDataSource
,底层使用XADataSource
。 - harshavmb