【问题标题】:Connection behavior - DriverManager.getConnection() and DataSource.getConnection()连接行为 - DriverManager.getConnection() 和 DataSource.getConnection()
【发布时间】:2012-09-22 05:29:19
【问题描述】:

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

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

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

【问题讨论】:

    标签: java jdbc connection resultset


    【解决方案1】:

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

    现在如果我们假设DataSource 提供连接池,那么DataSource 本身使用ConnectionPoolDataSource(或类似的内部机制)来获取PooledConnection。此 PooledConnection 管理与数据库的实际物理连接。

    当用户从 DataSource 请求连接时,DataSource 将检出一个 PooledConnection,并要求它提供一个Connection。 PooledConnection 然后将创建一个使用或包装物理连接的逻辑连接(例如使用代理)。 DataSource 会将该逻辑连接返回给用户。

    对于用户来说,逻辑连接的行为应该在所有方面都与物理连接相同。因此,当用户关闭连接时,该逻辑连接和所有相关的 JDBC 对象都将关闭,其行为与物理连接关闭相同。

    JDBC 4.1 第 11.1 节说:

    连接池对客户端是完全透明的:客户端获得一个连接池 连接和使用它的方式与获取和使用非池连接的方式相同。

    第 11.4 节:

    如果应用程序尝试重用逻辑句柄,连接实现 抛出 SQLException。

    对于给定的 PooledConnection 对象,只有最近生成的逻辑 Connection 对象才有效。调用关联的 PooledConnection.getConnection 方法时,任何先前存在的 Connection 对象都会自动关闭。

    然而,在后台,当逻辑连接关闭时,PooledConnection 将向 DataSource 发出信号表明它可以重用,然后 DataSource 会将其返回到连接池,或者关闭 PooledConnection(关闭物理连接) 如果它不再需要连接。

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

    【讨论】:

    • 在我的应用程序中,即使我关闭了Connection 对象,我也可以访问我的ResultSet 对象。因此,正如您所指出的,Websphere 未能实现这个实现?
    • 这取决于您对访问权限的含义。 ResultSet 对象仍将存在,但您应该无法使用 ResultSet,因为它应该在逻辑连接关闭时已关闭。
    • 如果它是一个不正确的 WebSphere 实现:这取决于你使用什么作为 ConnectionPoolDataSource 用于 websphere 的 DataSource。我描述的行为应该由PooledConnection 实现来强制执行。
    【解决方案2】:

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

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

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

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

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

    【讨论】:

    • 从连接池获得的逻辑连接的行为(对用户而言)应该与从 DriverManager 获得的物理连接完全相同。所以对于用户来说,即使物理连接保持打开状态,连接和所有依赖对象都应该看起来是关闭的。如果数据源实现表现不同,则它不符合 JDBC 规范。
    【解决方案3】:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-03-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-04-29
      • 1970-01-01
      相关资源
      最近更新 更多