Jdbc jConnect4池连接无法按文档所述工作

Jdbc jConnect4池连接无法按文档所述工作,jdbc,sybase,jconnect,Jdbc,Sybase,Jconnect,建议使用池连接的以下方法: SybConnectionPoolDataSource connectionPoolDataSource = new SybConnectionPoolDataSource(); ... Connection ds = connectionPoolDataSource.getConnection(); ... ds.close(); 然而,getDataSource总是导致异常。我反编译了SybConnectionPoolDataSource,发现该方法调用显式生成

建议使用池连接的以下方法:

SybConnectionPoolDataSource connectionPoolDataSource = new SybConnectionPoolDataSource();
...
Connection ds = connectionPoolDataSource.getConnection();
...
ds.close();
然而,getDataSource总是导致异常。我反编译了SybConnectionPoolDataSource,发现该方法调用显式生成错误:

public Connection getConnection() throws SQLException
{
    ErrorMessage.raiseError("JZ0S3", "getConnection()");
    return null;
}

有人知道为什么文档与实现相矛盾吗?

我不能专门针对Sybase发表评论,因为1)我不使用它,2)你的链接不起作用,但我可以根据我自己维护JDBC驱动程序(Jaybird/Firebird JDBC)的经验尝试给你一个理论然后看看其他一些实现的功能

可能是JDBCAPI中理解最少的部分。与命名建议和在某些JDBC实现中的实现方式相反,此接口不应提供连接池,也不应实现
DataSource
(或者至少:这样做可能导致混淆和错误;我自己的经验)

ConnectionPoolDataSource
的javadoc不是很有用,包文档提供了更多的信息,但是您确实需要查看JDBC 4.1规范,第11章连接池来了解它应该如何工作:

[…]JDBC驱动程序提供了应用服务器用来构建和管理连接池的
ConnectionPoolDataSource
的实现

换句话说:
ConnectionPoolDataSource
不是供开发人员直接使用,而是供应用服务器用于其连接池;它本身不是一个连接池

应用服务器为其客户机提供了
数据源
接口的实现,该接口使连接池对客户机透明

因此,通过正常的
数据源
实现,用户可以使用连接池。用户使用此连接时,将其视为不提供池的连接,并使用获得的连接时,将其视为正常物理连接,而不是从连接池获得的连接:

当应用程序使用连接完成时,它将使用方法
connection.close
关闭逻辑连接。这会关闭逻辑连接,但不会关闭物理连接。相反,物理连接会返回到池中,以便可以重用

连接池对客户机是完全透明的:客户机获得池连接并使用它的方式与获得和使用非池连接的方式相同

(由
ConnectionPoolDataSource创建的对象)的文档进一步支持了这一点:

应用程序程序员不直接使用
PooledConnection
接口;而是由管理连接池的中间层基础结构使用

当应用程序调用方法
DataSource.getConnection
时,它会返回一个
连接
对象。如果正在进行连接池,则该
连接
对象实际上是
池连接
对象的句柄,该对象是物理连接

连接池管理器(通常是应用程序服务器)维护一个
PooledConnection
对象池。如果池中有可用的
PooledConnection
对象,则连接池管理器将返回一个
connection
对象,该对象是该物理连接的句柄。如果没有可用的
PooledConnection
对象,连接池管理器将调用
ConnectionPoolDataSource
方法
getPoolConnection
来创建新的物理连接。实现
ConnectionPoolDataSource
的JDBC驱动程序创建一个新的
PooledConnection
对象并返回一个句柄

不幸的是,一些JDBC驱动程序通过在一个类中实现
DataSource
ConnectionPoolDataSource
来创建提供连接池的数据源,而不是JDBC规范的意图,即拥有
DataSource
使用
ConnectionPoolDataSource
。这导致实现在用作正常的
数据源时可以工作,但在用作
连接池数据源时(例如在应用程序服务器的连接池中)会中断,或者接口被误解,用于创建连接的方法错误(例如调用
getPooledConnection().getConnection()

我见过一些实现(包括在Jaybird中),其中使用
getPooledConnection()
访问实现内部的连接池,或者只从
getConnection()获取连接
的实现将正常工作,当使用该实现使用
getPooledConnection()
填充应用程序服务器中的连接池时,会导致各种异常和错误行为


也许Sybase做了类似的事情,然后认为这不是一个好主意,所以他们更改了
DataSource.getConnection()
抛出异常以确保它不是以这种方式使用的,但同时通过不删除
DataSource
定义的方法来保持API的兼容性。或者他们可能扩展了一个普通的
DataSource
以轻松创建物理连接(而不是包装一个普通的连接),但不希望用户将其用作数据源,我不能专门为Sybase发表评论,因为1)我不使用它,2)你的链接不起作用,但我可以根据我自己维护JDBC驱动程序(Jaybird/Firebird JDBC)的经验,尝试给你一个理论,并看看其他一些实现的功能

可能是JDBCAPI中理解最少的部分。与命名规则相反