9

DriverManager.getConnection()如果我使用and获得连接对象DataSource.getConnection(),在这些对象上调用它们时它们的行为有何不同.close()

.close()方法调用之前,我从这两个不同的连接中获得了相关的Statement和对象。ResultSet获得这两个对象后不久,如果我说connection1.close()(通过DriverManager.getConnection()),它将使连接对象无效,并且我不应该/不允许访问相关的 Statement 和 ResultSet 对象。如我错了请纠正我?

第二种情况,现在如果我说connection2.close()(通过DataSource.getConnection()),它只是将它返回到池中。但连接仍然存在。我可以访问关联的StatementResultSet对象吗?

4

3 回答 3

6

如果我们假设一个(基本的)DataSource(即:一个不做连接池的),那么您获得的物理连接与从DriverManager(一些驱动程序甚至在内部使用来自 DataSource 的 DriverManager 或来自 DriverManager 的 DataSource )。因此,这些连接的行为将相同。

现在,如果我们假设 aDataSource提供连接池,那么 DataSource 本身使用 a ConnectionPoolDataSource(或类似的内部机制)来获取 a 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(关闭物理连接)不再需要连接。

DataSource 还可以通过要求 PooledConnection 关闭逻辑连接来强制撤销用户的连接(例如,当连接签出时间过长时等)。

于 2012-09-22T08:11:28.213 回答
3

connection1.close()(通过 DriverManager.getConnection()),

这将关闭与数据库和所有资源建立的物理连接,即。结果集、语句、连接已发布。因此,连接关闭后您将无法访问它们。

connection2.close()(通过 DataSource.getConnection())

这是依赖于 DataSource 实现的,因此行为不需要在不同的 DataSource 实现之间保持一致。此外,在给定的 DataSource 实现中,连接的实际生命周期取决于各种其他参数,强烈建议不要将此连接与通过 DriverManager 获得的连接区分开来。

如果您真的希望在and关闭ResultSet后保留在 中的数据,您可以查看它是否适合您的用例。StatementConnectionCachedRowSet

于 2012-09-22T07:16:08.100 回答
3

客户端缓存可能取决于用于连接不确定的驱动程序。但是,一旦连接关闭,某些驱动程序会特别阻止您使用语句或结果集。其他人在客户端维护结果集

于 2012-09-22T08:03:45.483 回答