我不能专门针对 Sybase 发表评论,因为 1)我不使用它,并且 2)您的链接不起作用,但我可以根据自己维护 JDBC 驱动程序的经验(Jaybird/Firebird JDBC)尝试给您一个理论) 并查看其他一些实现的作用。
这ConnectionPoolDataSource
可能是 JDBC API 中最不被理解的部分。与命名所暗示的内容以及它在某些 JDBC 实现中的实现方式相反,此接口不应该提供连接池,也不应该实现DataSource
(或者至少:这样做会导致混乱和错误;我自己的经验)。
的 javadocConnectionPoolDataSource
不是很有帮助,javax.sql
包文档提供了更多信息,但是您确实需要查看 JDBC 4.1 规范,第 11 章连接池以很好地了解它应该如何工作:
[...] JDBC 驱动程序提供了ConnectionPoolDataSource
应用服务器用来构建和管理连接池的实现。
换句话说:ConnectionPoolDataSource
不是供开发人员直接使用,而是由应用程序服务器用作其连接池;它本身不是连接池。
应用程序服务器为其客户端提供DataSource
接口的实现,使连接池对客户端透明。
因此,连接池通过正常DataSource
实现对用户可用。用户将其用作不提供池的连接,并使用获得的连接,就好像它是普通的物理连接一样,而不是从连接池中获得的连接:
当应用程序使用完一个连接后,它会使用 方法关闭逻辑连接Connection.close
。这会关闭逻辑连接,但不会关闭物理连接。而是将物理连接返回到池中,以便可以重复使用。
连接池对客户端是完全透明的:客户端获得一个池连接并使用它,就像它获得和使用非池连接一样。
PooledConnection
(由 a 创建的对象)的文档进一步支持了这一点ConnectionPoolDataSource
:
应用程序员不PooledConnection
直接使用接口;相反,它由管理连接池的中间层基础设施使用。
当应用程序调用该方法DataSource.getConnection
时,它会返回一个Connection
对象。如果正在执行连接池,则该Connection
对象实际上是一个PooledConnection
对象的句柄,它是一个物理连接。
连接池管理器(通常是应用程序服务器)维护PooledConnection
对象池。如果PooledConnection
池中有可用的对象,则连接池管理器返回一个Connection
对象,该对象是该物理连接的句柄。如果没有PooledConnection
可用的对象,则连接池管理器调用该ConnectionPoolDataSource
方法getPoolConnection
来创建新的物理连接。JDBC 驱动程序实现ConnectionPoolDataSource
创建一个新PooledConnection
对象并返回一个句柄。
不幸的是,一些 JDBC 驱动程序已经创建了数据源,这些数据源通过在单个类中实现两者来提供连接池,而不是 JDBC 规范DataSource
的意图是使用. 这导致实现如果用作 normal 可以工作,但如果用作 a (例如在应用程序服务器的连接池中),或者接口被误解以及用于创建连接的方法错误(例如打电话)。ConnectionPoolDataSource
DataSource
ConnectionPoolDataSource
DataSource
ConnectionPoolDataSource
getPooledConnection().getConnection()
我已经看到了实现(包括在 Jaybird 中),其中getPooledConnection()
将用于访问实现内部的连接池,或者只有从getConnection()
实现中获得的连接才能正常工作,导致实现时出现各种奇怪和不正确的行为用于填充应用程序服务器中的连接池,使用getPooledConnection()
.
也许 Sybase 做了类似的事情,然后认为这不是一个好主意,所以他们更改了DataSource.getConnection()
抛出异常以确保它不以这种方式使用,但同时通过不删除定义的方法DataSource
。或者也许他们扩展了一个普通DataSource
的以轻松创建物理连接(而不是包装一个普通的连接),但不希望用户将其用作DataSource
.