如果我使用DriverManager.getConnection()
和DataSource.getConnection()
获取连接对象,那么在对这些对象调用.close()
时它们的行为有何不同?
在.close()
方法调用之前,我从这两个不同的连接中获得了相关的Statement
和ResultSet
个对象。获得这两个对象后不久,如果我说connection1.close()
(通过DriverManager.getConnection()
),它将使连接对象无效,我不应该/允许访问相关的Statement和ResultSet对象。如果我错了,请纠正我?
第二种情况,现在,如果我说connection2.close()
(通过DataSource.getConnection()
),它只会将其返回到池中。但这种联系仍然存在。我是否可以访问关联的Statement
和ResultSet
对象?
答案 0 :(得分:6)
如果我们假设(基本)DataSource
(即:不进行连接池的那个),那么您获得的物理连接与从DriverManager
获得的物理连接相同(某些驱动程序)甚至在内部使用来自DataSource的DriverManager,或来自DriverManager的DataSource)。所以那些连接的行为会相同。
现在,如果我们假设提供连接池的DataSource
,那么DataSource本身使用ConnectionPoolDataSource
(或类似的内部机制)来获取PooledConnection
。此PooledConnection管理与数据库的实际物理连接。
当用户从DataSource请求连接时,DataSource将检出PooledConnection,并询问它是否为Connection
。然后,PooledConnection将创建使用或包装物理连接的逻辑连接(例如,使用代理)。 DataSource将该逻辑连接返回给用户。
对于用户,逻辑连接的行为应与所有方面的物理连接相同。因此,当用户关闭连接时,该逻辑连接和所有相关的JDBC对象将被关闭,并且行为与物理连接关闭相同。
JDBC 4.1第11.1节说:
连接池对客户端完全透明:客户端获取池 连接和使用它的方式与获取和使用非池连接的方式相同。
第11.4节:
如果应用程序尝试重用逻辑句柄,则执行Connection 抛出一个SQLException。
和
对于给定的PooledConnection对象,只有最近生成的逻辑Connection对象才有效。调用关联的PooledConnection.getConnection方法时,将自动关闭任何以前存在的Connection对象。
然而,在后台,当逻辑连接关闭时,PooledConnection将向DataSource发出可供重用的信号,然后DataSource将其返回到连接池,或关闭PooledConnection(关闭物理连接) )如果它不再需要连接。
通过要求PooledConnection关闭逻辑连接,DataSource也可以强制撤销用户的连接(例如,当连接签出时间过长等),等等。
答案 1 :(得分:3)
connection1.close()(通过DriverManager.getConnection()),
这将关闭建立到数据库的物理连接和所有资源即。结果集,语句,连接已发布。因此,在关闭连接后,您无法访问它们。
connection2.close()(通过DataSource.getConnection())
这是依赖于DataSource的实现,因此行为不需要在不同的DataSource实现之间保持一致。此外,在给定的DataSource实现中,连接的实际生命周期取决于各种其他参数,强烈建议不要将此Connection与通过DriverManager获取的Connection区分开来。
如果您确实希望在ResultSet
和Statement
关闭后Connection
中保存的数据可用,您可以查看CachedRowSet
你的用例。
答案 2 :(得分:3)
客户端缓存可能依赖于用于连接的驱动程序而不确定。 但是一些驱动程序专门阻止您在关闭连接后使用语句或结果集。其他人在客户端维护结果集