【问题标题】:org.h2.jdbc.JdbcSQLException: The object is already closedorg.h2.jdbc.JdbcSQLException:对象已经关闭
【发布时间】:2018-05-03 17:46:20
【问题描述】:

对于我的生活,我无法看到它“已经关闭”

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;


public class RsetTest2 {

    public static void main(String[] args) throws Exception {
        String dbpath = "jdbc:h2:c:/mydb;IFEXISTS=TRUE;DB_CLOSE_ON_EXIT=FALSE;AUTO_SERVER=TRUE";

        Connection conn = null;
        System.setProperty("h2.bindAddress", "127.0.0.1");
        Class.forName("org.h2.Driver");
        conn = DriverManager.getConnection(dbpath, "sa", "sa"); 
        conn.setAutoCommit(false);
        System.out.println("success.  querying database for latest values...");

        Statement qry = conn.createStatement();
        String sql = "select id from CONSTITUENTS where manager = 'abc' limit 1";                               
        ResultSet rset = qry.executeQuery(sql);
        while (rset.next()) {
            int id = rset.getInt("id");
            System.out.println(id);         
            qry.executeUpdate("insert into PAYREQUESTS (constituent, inblock) values (" + id + ", 238)");
        }
        rset.close();
        qry.close();    
    }
}

这是输出:

success.  querying database for latest values...
103
Exception in thread "main" org.h2.jdbc.JdbcSQLException: The object is already closed [90007-196]
    at org.h2.message.DbException.getJdbcSQLException(DbException.java:345)
    at org.h2.message.DbException.get(DbException.java:179)
    at org.h2.message.DbException.get(DbException.java:155)
    at org.h2.message.DbException.get(DbException.java:144)
    at org.h2.jdbc.JdbcResultSet.checkClosed(JdbcResultSet.java:3208)
    at org.h2.jdbc.JdbcResultSet.next(JdbcResultSet.java:130)
    at RsetTest2.main(RsetTest2.java:22)

其中 22 对应于“while (rset.next()) {”行

数据库正在返回值,请参阅给出 103 的 println 语句。

甚至更奇怪的是,如果我 // 注释掉 executeUpdate 行,一切都会正常完成

【问题讨论】:

    标签: java h2 resultset


    【解决方案1】:

    线程 "main" org.h2.jdbc.JdbcSQLException 中的异常:对象已关闭 [90007-196]

    您的问题是您在 while 循环中重用了 SQL Statement。只要在循环中调用qry.executeUpdate(...) 方法,与前一个语句关联的ResultSet rset 就会关闭,因此会出现错误。在失败的循环中,第一个executeUpdate(...) 之后调用的是while(rset.next()) 语句。

    如果您在循环中使用 new 语句,那么它应该可以工作。

    Statement qry = conn.createStatement();
    String sql = "select id from CONSTITUENTS where manager = 'abc' limit 1";
    ResultSet rset = qry.executeQuery(sql);
    while (rset.next()) {
        int id = rset.getInt("id");
        System.out.println(id);
        // we can't reuse the same Statement here so we need to create a new one
        conn.createStatement().executeUpdate("insert into PAYREQUESTS ...");
    }
    

    您可以考虑保留必要更新的集合,然后在循环结束时发布更新。

    甚至更奇怪的是,如果我 // 注释掉 executeUpdate 行,一切都会正常完成

    是的,听起来不错。一点都不奇怪。 :-)

    【讨论】:

    • hg.openjdk.java.net/jdk7/jdk7/jdk/file/tip/src/share/classes/…,在关闭方法中表示如果它已经关闭,它应该是一个空操作。所以可能是驱动器实施问题。
    • 不是关闭@Yogesh_D,而是关闭后他还在使用rset
    • 知道了.. while(rset.next()) 是导致问题的原因,而不是关闭。谢谢!
    【解决方案2】:

    此外,为了简化您的代码,您可以使用
    java.lang.AutoCloseable 接口的 try-with-resources 语句,这样您就可以去掉行:

        rset.close();
        qry.close();  
    

    整个区块可能看起来像这样:

            try (ResultSet rset = conn.createStatement().executeQuery("select id from CONSTITUENTS where manager = 'abc' limit 1")) {
                String insertSQL = "insert into PAYREQUESTS (constituent, inblock) values ('%d', 238)";
                while (rset.next()) {
                    int id = rset.getInt("id");
                    Savepoint savePoint = conn.setSavepoint("beforeInsert");
                    try {
                        conn.createStatement().executeUpdate(String.format(insertSQL, id));
                        conn.commit();
                    } catch (SQLException ex) {
                        conn.rollback(savePoint);
                        //log exception
                    }
                }
            } catch (SQLException e) {
                //log exception
            }
    

    由于您的连接具有自动提交模式,等于 false 可能对可能的有害操作有意义。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2022-06-22
      • 2020-04-23
      • 2013-05-24
      • 1970-01-01
      • 1970-01-01
      • 2016-01-29
      • 2017-08-17
      相关资源
      最近更新 更多