【发布时间】:2018-12-26 18:24:30
【问题描述】:
我搜索了 getConnection().commit() (1) 与 getConnection().setAutoCommit(true) (2) 之间的区别。但是大多数情况只是描述(1)是默认方法,很少使用它来代替(2),或者两种方法都是“不同的目的”和相同的结果。
我使用 Oracle 文档中的示例
(https://docs.oracle.com/javase/tutorial/jdbc/basics/transactions.html#commit_transactions):
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);
}
}
}
在这个例子中,我不知道finally 块中con.setAutoCommit(true) (1) 的用途,因为每个任务都已经从try 块提交,尽管它可能会发生异常。谁能给我一个清楚的解释什么时候应该使用(1)?非常感谢您的帮助。
如果默认方法是true,那么我只是简单地做一个commit()而不是(1)来结束一个事务块,下一个块方法(不需要管理这个块的事务)将是变为默认模式(1)并且我不需要再次将其设置为true?
我有一个假设,con.commit() 只是提交语句,它仍然会在 (1) 被再次调用之前锁定某些行/表。我想我误解了commit() 会自动将当前默认设置为true 而不是再次尝试调用(1),因为我已经测试了一些代码,在调用commit() 之后,来自行/表的所有锁都会全部释放,所以我的假设也是错误的。
【问题讨论】:
-
如果您将其设置为
true,则每条语句都是它自己的事务。这在某种程度上违背了符合 ACID 的 RDBMS 的目的。在这个例子中,程序员希望所有查询都成功或都不成功——这是 ACID 中的 A——原子性。简而言之,autoCommit在实际应用程序中应该永远是true- 它仅适用于玩具/点头用例。 -
(虽然这个例子看起来很糟糕,因为两个更新更新了同一张表的同一行)
-
嗯,我在 Oracle 文档上搜索过,他们说“语句 con.setAutoCommit(true); 启用自动提交模式,这意味着每个语句在完成时会再次自动提交. 然后,您回到默认状态,您不必自己调用方法提交..." 这意味着如果我使用
commit()或rollback(),则翻译将完成并且我不需要@ 987654339@ (1) 不再是因为它是默认状态,对吧?我只是怀疑什么时候应该使用 (1) 或者它是旧的支持并且 commit() 是更新的可以替换 (1) 或者我误解了什么?