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