关闭 ResultSet 但不关闭 PreparedStatement

Closing ResultSet but not closing PreparedStatement

如果 ResultSet 关闭但 PreparedStatement 不关闭,我预计会发生什么类型的资源泄漏。非常可疑,它会导致打开游标问题...

   PreparedStatement p = connection.prepareStatement(...);
    try {
      ResultSet r = p.executeQuery();
      try {
        while (r.next()) {
          ....
        }
      } finally {
        try {
          r.close();
        } catch (SQLException e) {
        // log this or something -- prevent these from masking original exception
        }
      }
    }

是Oracle 11g,jdbc11.2.0.3

谢谢

请尝试回答我的问题,不要专注于修复

What type of resource leak can I expect if ResultSet is closed, but PreparedStatement not ?

泄漏将是最大打开游标问题。

ORA-01000: maximum open cursors exceeded

如果超过最大打开游标数,数据库将变得不可用,除了已经持有的游标。但是,大多数情况下发生这种情况时,甚至不会使用保持的游标(您的问题就是这种情况)。


自 java 7 以来,处理此问题的最佳方法是使用 try with ressourcesResultSetPreparedStatement 都实现了 AutoCloseable 接口,这意味着它们将在不再需要时关闭。

如果您没有 java 7,则需要在 finally 块中处理此问题,但请确保在关闭之前验证空值,否则您可能会遇到 NPE,如果资源从未初始化。

请注意,反向操作不会造成任何问题,因为关闭语句会自动关闭它的结果集。


请注意,您可以轻松地为您的应用程序允许更多游标,以减少超过最大值的可能性。

ALTER SYSTEM SET open_cursors = 400 SCOPE=BOTH;

但是,大多数情况下,如果遇到最大打开游标,这不应该是解决方案,因为它只会隐藏真正的问题。

可能在 Oracle 中,您不会在数据库服务器端冒太多风险。准备好的语句在库缓存中共享,当语句不被执行时,Oracle 可以摆脱它。

但不管怎么说这是个很不好的习惯。 JDBC driver side. 上发生的事情也值得怀疑 这是 OCI 文档的摘录,但我认为 JDBC 行为将是相似的:

Statement Caching without Session Pooling in OCI

Users perform the usual OCI steps to logon. The call to obtain a session will have a mode that specifies whether statement caching is enabled for the session. Initially the statement cache will be empty. Developers will try to find a statement in the cache using the statement text. If the statement exists the API will return a previously prepared statement handle, otherwise it will return a newly prepared statement handle.

因此,当在客户端使用 PreparedStatement 缓存时,看起来 Oracle 甚至可以避免软解析。因此,当您不关闭 PreparedStamement 时,您可能会遇到此缓存问题。

注意:映射是 RecultSet => "open cursor",而 PreparedStatement 可能映射到库缓存中的条目。对于 Oracle,关闭 ResultSet 是至关重要的。

PS:与 Informix(PostgreSQL 和其他 RDBMS)相反,执行计划不共享,每个会话 process/thread 都有自己的准备好的语句集。因此,当使用其他数据库时,您可能会遇到严重的麻烦。