【问题标题】:Connection.rollback() doesn't work in JavaConnection.rollback() 在 Java 中不起作用
【发布时间】:2021-09-20 14:32:42
【问题描述】:

我编写了这个函数来轻松填充我的数据库(mySQL):

public boolean addItems(Connection con) throws SQLException {
    try {
        con.setAutoCommit(false);
        String[] brands = { "Honda", "BMW", "Mercedes Benz" };
        String[] optional = { "acciaio", "alluminio", "carbonio", "titanio" };
        Statement statement = con.createStatement();
        for (int i = 0; i < brands.length; i++) {
            for (int j = 0; j < optional.length; j++) {
                statement.executeUpdate("INSERT INTO chassis (idUnit, brand, material, availableItems) VALUES (1, '" + brands[i] + "', '" + optional[j] + "', 20)");
                statement = Condb.replaceStatement(statement);
                ResultSet rs = statement.executeQuery("SELECT * FROM chassis WHERE brand = '" + brands[i] + "' AND material = '" + optional[j] + "'");
                while (rs.next()) {
                    statement = Condb.replaceStatement(statement);
                    statement.executeUpdate("INSERT INTO product_code (unitName, productCode, brand, optional) VALUES ('chassis', " + rs.getInt("productCode") + ", '" + brands[i] + "', '" + optional[j] + "')");
                    con.commit();
                }
            }
        }
        return true;
    } catch (Exception exception) {
        exception.printStackTrace();
        con.rollback();             
        return false;
    }
}

但是它在'chassis'表中添加了一条记录(第一次更新),然后它没有进入while循环('productCode'字段是一个自动增量字段,所以我需要按顺序从机箱表中获取它在“product_code”表中添加记录)。 之后,它增加 j 变量,在机箱表中执行更新,进入 while 循环并在更新时(在循环中)抛出 SQLException

ResultSet 关闭后不允许操作

但它从不执行回滚。所以我的机箱表中有记录,但 product_code 表是空的。 这是我的 replaceStatement 函数:

public static Statement replaceStatement(Statement stmt) {
    try {
        stmt.close();
        Statement statement = Condb.initializeDatabase().createStatement();
        return statement;
    } catch (Exception e) {
        e.printStackTrace();
    }
    return null;
}

谁能帮我解决这个问题?

【问题讨论】:

  • 为什么不使用单独的Statement 对象?为INSERT 创建一个,为SELECT 创建另一个。还可以考虑使用PreparedStatement 而不是Statement,还可以考虑使用try-with-resources。
  • 您在while 循环内提交,但您没有先在for 循环内提交INSERT INTO
  • 至于你的根本问题(错误"Operation not allowed after ResultSet closed"),你需要为选择和插入使用单独的Statement对象,见还有Operation not allowed after ResultSet closed when deleting from a database 和类似的问题。

标签: java mysql jdbc rollback autocommit


【解决方案1】:

您不能提交然后请求回滚。对于与普通 JDBC 一起使用的连接,要么在最后进行一次提交,要么在某些语句失败时触发回滚。

所以con.commit(); 应该放在return true 之前

否则,您可以按照此答案 https://stackoverflow.com/a/47482143/7237884 在循环中手动处理多个事务

【讨论】:

  • 感谢您和@Abra 的回复,现在它可以工作了。但是我试图在 con.commit() 之前抛出一个异常,但我的表中仍然有所有插入的记录。这怎么可能?
  • 发布您当前的代码以了解您的意思
猜你喜欢
  • 2017-09-01
  • 2018-05-15
  • 2015-05-27
  • 2015-11-23
  • 2014-02-12
  • 2015-01-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多