在应用程序服务器环境中,是否应该更喜欢javax.sql.DataSource或javax.sql.ConnectionPoolDataSource?

Lai*_*son 5 jdbc java-ee

一个现有的问题表达了类似的东西,但我想在这里提出一个稍微不同的细微差别.

基本问题:当您定义连接池时,所有应用程序服务器能够为(little-d,little-s)数据源指定(标准)接口(供应商提供的)实现类.如果供应商提供a ConnectionPoolDataSource和常规ol'的实现DataSource,哪一个是首选?

怎么样为实现供应商实现DataSource,ConnectionPoolDataSourceXADataSource在同一个实现类?

javax.sql.ConnectionPoolDataSource所说的文档几乎总是如此:

PooledConnection对象的工厂.实现该接口的对象通常将与基于所述的JavaTM命名和目录接口(JNDI)的命名服务注册.

这基本上没用,但值得注意的是,javax.sql.ConnectionPoolDataSource它本身并没有扩展javax.sql.DataSource,这意味着它的实现不需要提供一个getConnection()方法,这是大多数调用者习惯使用的方法.这告诉我所有应用程序服务器必须:

  • javax.sql.ConnectionPoolDataSource实现包装实现,javax.sql.DataSource以便调用者可以使用javax.sql.DataSource#getConnection(),或

  • 检测到一个javax.sql.ConnectionPoolDataSource实现也是一个javax.sql.DataSource实现,以及(在某种程度上)的信任,其getConnection()方法将委托给getPooledConnection()(如何在地球上,他们将做到这一点?)

文档javax.sql.DataSource部分说:

DataSource接口由驱动程序供应商实现.有三种类型的实现:

  • 基本实现 - 生成标准Connection对象
  • 连接池实现 - 生成一个将自动参与连接池的Connection对象.此实现适用于中间层连接池管理器.
  • 分布式事务实现 - 生成可用于分布式事务的Connection对象,并且几乎总是参与连接池.此实现与中间层事务管理器一起使用,并且几乎总是与连接池管理器一起使用.

这也是无用的,并且引导不正确(或至少未指定:javax.sql.DataSource也由应用服务器供应商实现,他们必须提供实现,以便客户端代码可以(例如)将a javax.sql.DataSource注入其服务器端代码中).它似乎也暗示任何给定的DataSource实现可能会或可能不会提供连接池,这会让我想知道应用服务器应该如何设置指定javax.sql.DataSource接口(而不是javax.sql.ConnectionPoolDataSource接口)的连接池.

注:我不是在寻找一个答案约我这是怎么在Tomcat,或者我把对工作对我来说,或者性质的任何GlassFish的步骤在这里.我正在寻找一个回答JDBC规范,Java EE规范或错误报告的答案,或者说明为什么存在这些独立(无关!)接口的原因,以及它们应该如何统一或区分在通用Java EE应用程序服务器之间,因此有义务提供连接池.

Mar*_*eel 0

您不应该ConnectionPoolDataSource直接使用 a,它的目的是作为物理连接(也称为 s)的源,然后由实际实现连接池的PooledConnectiona 使用。DataSourceAConnectionPoolDataSource本身不应该实际实现池化。

\n\n

例如,这样的数据源由您的应用程序服务器提供。它通常需要一个 JNDI URL(或直接引用)ConnectionPoolDataSource,并且它本身公开DataSource接口来分发“逻辑”连接。

\n\n

DataSourceJDBC 4.1第 9.4 节中讨论了这些内容:

\n\n
\n

DataSource 接口 [..] 是获取数据源连接的首选方法。

\n
\n\n

\n\n
\n

逻辑名称通过使用 Java 命名和目录接口 (JNDI) 的命名服务映射到数据源对象。DataSource 对象代表物理数据源并提供与该数据源的连接。

\n
\n\n

如果我们再看一下简介中对连接池的描述(第11章):

\n\n
\n

JDBC 驱动程序提供 ConnectionPoolDataSource 的实现,应用程序服务器使用它来构建和管理连接池。

\n\n

用于管理连接池的算法是特定于实现的并且随应用程序服务器的不同而不同。应用程序服务器向其客户端提供 DataSource接口的实现,使连接池对客户端来说是透明的。因此,客户端在使用与以前相同的 JNDI 和 DataSource API 的同时,可以获得更好的性能和可扩展性。(强调我的)

\n
\n\n

DataSource(AS) (以下简称:ASDS)和(驱动程序) (以下简称:CPDS)之间的交互ConnectionPoolDataSource在第 11.1 - 11.3 节中描述。11.3节具体描述了交互:

\n\n
\n

以下步骤序列概述了当 JDBC 客户端从实现连接池的 DataSource 对象请求连接时会发生什么情况:

\n\n
    \n
  • 客户端调用DataSource.getConnection。
  • \n
  • 提供 DataSource 实现的应用程序服务器在其连接池中查找是否有合适的\n PooledConnection 对象\xe2\x80\x94 可用的物理数据库连接\xe2\x80\x94。\n 确定给定 PooledConnection 的适用性对象可能包括匹配客户端xe2x80x99s 用户身份验证信息或应用程序类型以及使用其他特定于实现的标准。查找方法和其他与管理连接池相关的方法特定于应用程序服务器。
  • \n
  • 如果没有合适的可用 PooledConnection 对象,应用程序服务器将调用 ConnectionPoolDataSource.getPooledConnection 方法来获取新的物理连接。实现 ConnectionPoolDataSource 的 JDBC 驱动程序创建一个新的 PooledConnection 对象并将其返回到应用程序服务器。
  • \n
  • 无论 PooledConnection 是从池中检索的还是新创建的,应用程序服务器都会执行一些内部记录以指示物理连接现在正在使用中。
  • \n
  • 应用服务器调用方法 PooledConnection.getConnection 来获取一个逻辑 Connection 对象。\n 这个逻辑 Connection 对象实际上是一个 \xe2\x80\x9chandle\xe2\x80\x9d 到一个物理\n PooledConnection 对象,就是这个句柄当连接池生效时,由 DataSource.getConnection 方法返回。
  • \n
  • 应用程序服务器通过调用方法\n PooledConnection.addConnectionEventListener 将自身注册为 ConnectionEventListener。这样做是为了在 PooledConnection 对象可供重用时通知应用程序服务器。
  • \n
  • 逻辑 Connection 对象返回到 JDBC 客户端,该客户端使用与基本 DataSource 情况相同的 Connection API。请注意,除非客户端调用 Connection.close 方法,否则基础 PooledConnection 对象无法重用。
  • \n
\n
\n\n

最后一项并不完全正确:ASDS 可以通过分发从客户端Connection获得的新连接来强制关闭/使来自客户端的逻辑连接无效PooledConnection(参见第 11.4 节)。

\n\n

现在回答您在评论中提出的问题:为什么 AS 允许您在数据源配置中同时指定 aDataSourceConnectionPoolDataSource接口:ASDS 和 CPDS 之间的引用通常也是通过 JNDI 完成的。例如,这允许轻松重新配置(将 ASDS 切换到不同的底层 CPDS,或者将 ASDS 切换到正常的基本数据源,同时仍然维护 CPDS 的配置,例如因为它也由不同的 ASDS 使用)。另请参见 JDBC 规范第 11.5 节:

\n\n
\n

部署实现连接池的 DataSource 对象要求客户端可见的 DataSource 对象和基础 ConnectionPoolDataSource 对象都注册到基于 JNDI 的命名服务。

\n
\n