为什么调用Statement.close()不能立即释放由Statement对象创建的ResultSet对象?

时间:2018-08-01 23:10:47

标签: java jdbc

来自JDBC Spec

  

关闭Statement对象将关闭并使任何实例无效   该Statement对象产生的ResultSet。 资源持有者   直到垃圾回收才可以释放ResultSet对象   再次运行,因此最好明确关闭ResultSet   不再需要它们的物体。

  • 调用ResultSet.close()是否立即释放ResultSet对象?

  • 调用Statement.close()是否立即释放Statement对象?

  • 调用Statement.close()会释放由Statement对象创建的ResultSet对象,那么为什么不立即释放ResultSet对象呢?

4 个答案:

答案 0 :(得分:2)

似乎根据ResultSet SE 8 #close()

立即发布了

Statement SE 8相同

ResultSet也会在关闭生成它的Statement对象时自动关闭。

  

当ResultSet对象关闭,重新执行或用于从多个结果序列中检索下一个结果时,将自动关闭ResultSet对象。

答案 1 :(得分:2)

摘自Statement.close()的Javadoc(强调我的):

  

释放此Statement对象的数据库和JDBC资源   立即,而不是等待它发生时   自动关闭。通常,释放是个好习惯   完成处理后尽快避免资源占用   数据库资源。

     

在已关闭的Statement对象上调用方法关闭   没有效果。

     

注意: Statement对象关闭时,其当前的ResultSet对象,   如果存在,也将关闭。

在这里,Javadoc指出立即关闭Statement 会释放其资源 也会关闭其当前的ResultSet

还有ResultSet.close()的Javadoc(我的强调):

  

释放此ResultSet对象的数据库和JDBC资源   立即,而不是等待它发生时   自动关闭。

     

关闭ResultSet对象不会关闭BlobClob或   NClob创建的ResultSet个对象。 BlobClobNClob对象   至少在交易持续时间内保持有效   它们会被创建,除非调用了它们的free方法。

     

关闭ResultSet时,所有ResultSetMetaData实例   通过调用getMetaData方法创建的文件仍可访问。

     

注意:ResultSet自动关闭Statement对象   Statement对象关闭时生成它的对象,   重新执行,或用于从以下序列中检索下一个结果   多个结果。

     

在已关闭的ResultSet对象上调用方法关闭   是没有人。

该Javadoc指出,关闭ResultSet也会立即释放其资源。而且,如上所述,调用Statement.close()也会关闭ResultSet

该注释还指出,在任何给定时间,每个ResultSet只能打开一个Statement。如果您提出另一个请求(或满足上述任何其他条件),则前一个ResultSet将自动关闭。

注意:所有Javadoc引号和链接均适用于Java 10。

答案 2 :(得分:1)

有关关闭JDBC对象的说明。

从Java SE 7开始,可以使用try-with-resources来管理JDBC对象。 ConnectionStatementResultSetRowSet接口扩展了java.lang.AutoCloseable。 try-with-resources语句可确保在语句末尾关闭每个资源(无论该块中的代码如何完成)。

这是一些Java和JDBC代码示例-请注意,该语句和结果集是在try-with-resources块中创建的。

public void printAllBooks()
        throws SQLException {
    String sql = "SELECT * FROM book_table";
    try(Statement stmnt = conn.createStatement(); // conn is the Connection object
        ResultSet rs = stmnt.executeQuery(sql)) {
        while (rs.next()) {
            System.out.println("Id: " + rs.getString("book_id") +
                    " Author: " + rs.getString("author") +
                    " Title: " + rs.getString("title"));
        }
    }
}

注意:

  • 一个人可以在try-with-resources中声明一个或多个资源 声明。
  • try-with-resources语句可以具有可选的catch和/或finally块。关闭声明的资源后,将运行任何catch或finally块。
  • 当try-with-resources紧随其后的代码块正常终止或由于异常而终止时,StatementResultSet的close()方法将在<与他们的创作相反。

答案 3 :(得分:1)

您误解了该句子的含义。根据应用程序中语句的使用方式,Statement对象的寿命可能比该语句产生的ResultSet的寿命长得多。因此,如果您不立即完成ResultSet的关闭,它将继续打开并保留资源,直到您关闭该语句或对该语句对象执行另一个查询为止,或者直到垃圾收集器可以收集结果集,它假定该语句对结果集没有强大的引用(而这很大程度上是实现特定的细节)。

换句话说,尽管语句close()将立即关闭结果集及其资源,但您不应该依赖该行为,而应尽快关闭结果集。

免责声明:我是JSR-221的JDBC专家组的成员