java - 什么时候我们需要调用java.sql.Connection.rollback()?

标签 java jdbc

我必须在一个函数中修改几个表。他们必须全部成功,否则全部失败。如果一项操作失败,我希望所有操作都失败。我有以下内容:

public void foo() throws Exception {
    Connection conn = null;
    try {
        conn = ...;
        conn.setAutoCommit(false);
        grok(conn);
        conn.commit();
    }
    catch (Exception ex) {
        // do I need to call conn.rollback() here?
    }
    finally {
        if (conn != null) {
            conn.close();
            conn = null;
        }
    }
}

private void grok(Connection conn) throws Exception {
    PreparedStatement stmt = null;
    try {
        // modify table "apple" 
        stmt = conn.prepareStatement(...);
        stmt.executeUpdate();
        stmt.close();

        // modify table "orange"
        stmt = conn.prepareStatement(...);
        stmt.executeUpdate();
        stmt.close();

        ...
    }
    finally {
        if (stmt != null) {
            stmt.close();
        }
    }
}

我想知道如果在此过程中出现问题,是否需要调用 rollback() 。

其他信息:我正在使用连接池。在上面的示例中,我还确保也使用finally 语句关闭每个PreparedStatement,只是为了简洁而省略了。

谢谢

最佳答案

是的,如果任何语句失败或者在调用提交之前检测到异常,则需要调用回滚。这是一篇旧帖子,但接受的答案是错误的。您可以自己尝试一下,在提交之前抛出异常,并观察如果不手动回滚,您的插入仍然会进入数据库。

JDBC 文档 https://docs.oracle.com/javase/tutorial/jdbc/basics/transactions.html#call_rollback

文档中的正确用法示例

public void updateCoffeeSales(HashMap<String, Integer> salesForWeek)
    throws SQLException {

    PreparedStatement updateSales = null;
    PreparedStatement updateTotal = null;

    String updateString =
        "update " + dbName + ".COFFEES " +
        "set SALES = ? where COF_NAME = ?";

    String updateStatement =
        "update " + dbName + ".COFFEES " +
        "set TOTAL = TOTAL + ? " +
        "where COF_NAME = ?";

    try {
        con.setAutoCommit(false);
        updateSales = con.prepareStatement(updateString);
        updateTotal = con.prepareStatement(updateStatement);

        for (Map.Entry<String, Integer> e : salesForWeek.entrySet()) {
            updateSales.setInt(1, e.getValue().intValue());
            updateSales.setString(2, e.getKey());
            updateSales.executeUpdate();
            updateTotal.setInt(1, e.getValue().intValue());
            updateTotal.setString(2, e.getKey());
            updateTotal.executeUpdate();
            con.commit();
        }
    } catch (SQLException e ) {
        JDBCTutorialUtilities.printSQLException(e);
        if (con != null) {
            try {
                System.err.print("Transaction is being rolled back");
                con.rollback();
            } catch(SQLException excep) {
                JDBCTutorialUtilities.printSQLException(excep);
            }
        }
    } finally {
        if (updateSales != null) {
            updateSales.close();
        }
        if (updateTotal != null) {
            updateTotal.close();
        }
        con.setAutoCommit(true);
    }
}

关于java - 什么时候我们需要调用java.sql.Connection.rollback()?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9901480/

相关文章:

java - gae 1.7.3 更新 -> java.io.InvalidClassException

java - JDBC 事务错误处理

postgresql - 如何通过jdbc获取数据库函数体?

java - 表列: Show only image

java - 如何在不使用 .stopAndWait 方法的情况下使用 Javafx 中警报中的按钮?

java - 当业务逻辑和数据层似乎重叠时,用于分解业务逻辑和数据层的最佳设计?

mysql - 想要连接具有多个条件的多个表

java - 将复选框添加到 jTable 中?

java - 服务器时区值 'CDT' 无法识别或代表多个时区

java - 序列化对象时包含外部变量