首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在应用服务器环境中,应该选择javax.sql.DataSource还是javax.sql.ConnectionPoolDataSource?

在应用服务器环境中,应该选择javax.sql.DataSource还是javax.sql.ConnectionPoolDataSource?
EN

Stack Overflow用户
提问于 2012-10-10 18:42:51
回答 2查看 2K关注 0票数 5

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

基本问题:在定义连接池时,所有应用服务器都能够为(小-d,小-s)数据源指定(标准)接口和(供应商提供的)实现类。如果供应商同时为ConnectionPoolDataSource和普通ol‘DataSource提供了一个实现,那么哪个是首选的?

对于在同一个实现类中实现DataSourceConnectionPoolDataSourceXADataSource的供应商实现呢?

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接口由驱动程序供应商实现。有三种类型的实现:

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

这也是无用的,而且引导也是不正确的(或者至少没有指定:javax.sql.DataSource也是由应用服务器供应商实现的,他们必须提供一个实现,以便客户机代码可以(例如)将一个javax.sql.DataSource注入到他们的服务器端代码中)。这似乎还意味着,任何给定的DataSource实现可能提供连接池,也可能不提供连接池,这使我想知道应用服务器应该如何判断何时设置了指定了javax.sql.DataSource接口(而不是javax.sql.ConnectionPoolDataSource接口)的连接池。

注意:,我不是在这里寻找答案,我是如何在Tomcat上做这件事的,或者我在GlassFish上所采取的步骤,这些步骤对我或类似的事情都有帮助。我正在寻找一个可以引用JDBC规范或Java规范的答案,或者一个bug报告,或者一些说明为什么这些独立(无关的!)的答案!接口是存在的,以及它们应该如何统一或区分在一般的Java应用服务器上,因此必须提供连接池。

EN

回答 2

Stack Overflow用户

发布于 2012-10-11 07:32:16

不应该直接使用ConnectionPoolDataSource,而是将其作为物理连接(也称为PooledConnection)的源,然后由实际实现连接池的DataSource使用。ConnectionPoolDataSource不应该实际实现池本身。

例如,这样的DataSource是由应用服务器提供的。它通常接受对ConnectionPoolDataSource的JNDI (或直接引用),并且它本身公开了DataSource接口以发出“逻辑”连接。

DataSource的讨论见JDBC 4.1第9.4节:

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

通过使用(JNDI)的命名服务将逻辑名称映射到DataSource对象。DataSource对象,表示物理数据源,并提供到该数据源的连接。

如果我们看一下介绍中对连接池的描述(第11章),我们就会指定:

JDBC驱动程序提供了ConnectionPoolDataSource的实现,应用服务器用于构建和管理连接池的。 用于管理连接池的算法是特定于实现的,并且随着应用服务器的不同而变化。--应用服务器向客户端提供DataSource接口的实现,使连接池对客户端透明。因此,当使用与以前相同的JNDI和DataSource API时,客户机获得了更好的性能和可伸缩性。(强调地雷)

第11.1-11.3节描述了(AS) DataSource (以下简称AS)与(驱动程序) ConnectionPoolDataSource (以下简称CPDS)之间的交互作用。第11.3节具体描述了相互作用:

以下步骤概述了JDBC从实现连接池的DataSource对象请求连接时发生的情况:

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

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

现在来看一下注释中的问题:为什么AS允许您在数据源配置中同时指定DataSourceConnectionPoolDataSource接口: ASDS和ConnectionPoolDataSource之间的引用通常也是通过JNDI完成的。例如,这允许简单的重新配置(将ASDS切换到另一个基础的DataSource,或者将ASDS切换到一个正常的基本的,同时仍然维护CPDS的配置-例如,因为它也被不同的ASDS使用)。还请参阅JDBC规范的11.5节:

部署实现连接池的DataSource对象需要向基于JNDI的命名服务注册客户机可见的DataSource对象和底层的ConnectionPoolDataSource对象。

票数 0
EN

Stack Overflow用户

发布于 2014-04-15 14:58:01

为了说明一下:我正在使用Postgres,来自PGConnectionPoolDataSource的API文档对我来说非常清楚:

代码语言:javascript
复制
public class PGConnectionPoolDataSource
extends org.postgresql.ds.jdbc4.AbstractJdbc4ConnectionPoolDataSource
implements javax.sql.ConnectionPoolDataSource

PostgreSQL ConnectionPoolDataSource的实现。应用服务器或中间件供应商应该为提供一个利用该ConnectionPoolDataSource的DataSource实现。如果不是,您可以使用--称为PoolingDataSource的PostgreSQL实现,但是只有当服务器或中间件供应商没有提供自己的时,才应该使用。为什么?服务器可能希望在请求同一事务内的连接的所有EJB之间重用相同的连接,或者提供其他类似的高级特性。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/12826191

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档