官方Sybase jConnect程序员参考建议使用池连接的方式如下:
SybConnectionPoolDataSource connectionPoolDataSource = new SybConnectionPoolDataSource();
...
Connection ds = connectionPoolDataSource.getConnection();
...
ds.close();然而,getDataSource总是会导致异常。我对SybConnectionPoolDataSource进行了解压缩,发现方法调用显式地生成了一个错误:
public Connection getConnection() throws SQLException
{
ErrorMessage.raiseError("JZ0S3", "getConnection()");
return null;
}有人知道为什么文档与实现相矛盾吗?
发布于 2013-04-09 18:58:02
我不能对Sybase进行专门的评论,因为1)我不使用它,2)您的链接不起作用,但我可以尝试根据我自己维护JDBC驱动程序(Jaybird/Firebird JDBC)和查看其他一些实现的经验,给出一个理论。
ConnectionPoolDataSource可能是JDBC中最不被理解的部分。与命名的含义以及在某些JDBC实现中是如何实现的相反,这个接口不应该提供连接池,也不应该实现DataSource (或者至少:这样做会导致混淆和错误;我自己的经验)。
ConnectionPoolDataSource的javadoc不是很有帮助,javax.sql包文档提供了一些更多的信息,但是您确实需要查看JDBC4.1规范,即第11章连接池,以便很好地了解它应该如何工作:
..。JDBC驱动程序提供了
ConnectionPoolDataSource的实现,应用服务器用于构建和管理连接池。
换句话说:ConnectionPoolDataSource不是开发人员直接使用的,而是应用服务器用于其连接池的;它本身不是一个连接池。
应用服务器向客户端提供
DataSource接口的实现,使连接池对客户端透明。
因此,连接池可以通过正常的DataSource实现向用户提供。用户将此用作不提供池的连接,并将所获得的连接用作正常的物理连接,而不是从连接池获得的连接:
当应用程序使用连接完成时,它将使用
Connection.close方法关闭逻辑连接。这将关闭逻辑连接,但不关闭物理连接。相反,物理连接将返回到池,以便可以重用它。 连接池对客户端是完全透明的:客户机获得一个池连接,并以它获得和使用非池连接的方式使用它。
PooledConnection的文档(由ConnectionPoolDataSource创建的对象)进一步支持了这一点:
应用程序程序员不直接使用
PooledConnection接口,而是由管理连接池的中间层基础结构使用。 当应用程序调用DataSource.getConnection方法时,它将获得一个Connection对象。如果正在执行连接池,则该Connection对象实际上是PooledConnection对象的句柄,这是一个物理连接。 连接池管理器(通常是应用服务器)维护一个PooledConnection对象池。如果池中有可用的PooledConnection对象,则连接池管理器将返回一个Connection对象,该对象是该物理连接的句柄。如果没有可用的PooledConnection对象,则连接池管理器将调用ConnectionPoolDataSource方法getPoolConnection来创建新的物理连接。实现ConnectionPoolDataSource的JDBC驱动程序创建一个新的PooledConnection对象并返回它的句柄。
不幸的是,一些JDBC驱动程序创建了数据源,通过在单个类中实现DataSource和ConnectionPoolDataSource来提供连接池,而不是JDBC规范的意图是让使用作为ConnectionPoolDataSource。这导致了如果作为普通DataSource使用的实现,但如果用作ConnectionPoolDataSource (例如在应用程序服务器的连接池中),或者接口被误解,以及用于创建连接的错误方法(例如调用getPooledConnection().getConnection()),则会中断。
我已经看到了一些实现(包括在Jaybird中),其中getPooledConnection()将用于访问实现内部的连接池,或者只有从实现的getConnection()获得的连接才能正确工作,当该实现用于使用getPooledConnection()填充应用服务器中的连接池时,会导致各种奇怪和错误行为。
也许Sybase做了一些类似的事情,然后认为这不是一个好主意,所以他们改变了DataSource.getConnection()以确保它不是以这种方式使用的异常,但是同时通过不删除DataSource定义的方法来保持API的兼容性。或者他们扩展了一个普通的DataSource来轻松地创建物理连接(而不是包装一个普通的),但是不希望用户将它作为一个DataSource使用。
https://stackoverflow.com/questions/15896872
复制相似问题