什么时候应在Java中使用setAutoCommit(true)

时间:2018-12-25 12:24:27

标签: java jdbc

我搜索了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);
        }
    }
}

在此示例中,我不知道con.setAutoCommit(true)块中finally(1)的用途,因为尽管已经发生了{不。谁能给我清楚的解释何时使用(1)?非常感谢您的帮助。

如果默认方法是try,那么我只需做一个true而不是(1)来结束一个事务块和下一个块方法(无需为此管理事务块)将变为默认模式(1),而我不需要再次将其设置为true吗?

我有一个假设,commit()只是提交语句,并且在再次调用(1)之前它仍然锁定了某些行/表。我想我误会了con.commit()会自动将当前默认值设置为commit(),而不是尝试再次调用(1),因为在调用全部true之后,我已经测试了一些代码行/表中的锁将全部释放,因此我的假设也是错误的。

1 个答案:

答案 0 :(得分:2)

在您向我们展示的示例中,代码关闭了自动提交,然后在最后将其打开。关闭自动提交功能后,它将在每次更新后一次重复执行两次更新。

在该示例中,应该明确最后关闭自动提交的目的。程序员(大概是!)想要执行更新对,并且在它们之间进行提交,因为一对更新对需要是自动完成的。如果您不关闭自动提交,则无法执行此操作。

finally块中重新启用自动提交的目的是将其恢复为默认状态。大概这样做是为了允许再次使用该连接。但是,有必要争论的是:

  • 打开或关闭自动提交几乎不需要任何费用。
  • 如果连接已经自动提交已关闭,则调用setAutoCommit(false)并没有什么害处。

在我看来,以上所述的结果是有两种明智的处理方式:

  • 如果整个应用程序需要显式事务,请在建立连接时关闭自动提交...,然后将其保留。

  • 如果应用程序的不同部分具有不同的自动提交要求,那么最简单的方法是让管理每个事务的代码将自动提交设置为所需的内容,然后不要打扰重置它。 / p>

finally块中恢复默认自动提交状态的5行左右的额外代码不会对我造成不必要的打击。的确,除非可以确保始终恢复自动提交状态,否则最好假设状态不确定。例如在updateCoffeeSales方法的开头...或在其他要启用自动提交的方法的开头。