Когда следует использовать setAutoCommit (true) в Java - PullRequest
0 голосов
/ 25 декабря 2018

Я искал разницу между getConnection().commit() (1) и getConnection().setAutoCommit(true) (2).Но в большинстве случаев просто опишите, что (1) является методом по умолчанию и редко его используете вместо (2), или оба метода имеют «разные цели» и один и тот же результат.Я использую пример на Oracle docs (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) (1) в блоке finally, потому что каждая задача уже была зафиксирована изtry блок, хотя это может произойти исключение или нет. Может кто-нибудь дать мне четкое объяснение, когда должен использовать (1)? Большое спасибо за помощь.

Если метод по умолчанию true, поэтому япросто сделать commit() вместо (1) для завершения блока транзакции, и следующий метод блока (не нужно управлять транзакцией для этого блока) перейдет в режим по умолчанию (1), и мне не нужноснова установить его в true?

У меня есть гипотеза, что con.commit() это просто фиксация оператора, и он все еще блокирует некоторую строку / таблицу до того, как (1) будет вызван снова. Я думаю, что я неправильно понимаю commit() автоматически установит текущее значение по умолчанию на true вместо попытки вызова (1) снова, потому что я протестировал некоторый код, после вызова commit() все блокировки из строки / таблицы будут сняты все, поэтому моя гипотезаwronг тоже.

1 Ответ

0 голосов
/ 25 декабря 2018

В примере, который вы нам показали, код отключает автокоммит, а затем включает его в конце.Когда функция автоматической фиксации отключена, она последовательно выполняет два обновления одновременно с фиксацией после каждой пары обновлений.

В этом примере цель отключения функции автоматической фиксации в конце должна быть понятной.Программист (предположительно!) Хочет выполнить пары обновлений с фиксацией между ними , потому что пара обновлений требует для атомарного выполнения.Если вы не отключите автокоммит, вы не сможете этого сделать.

Цель включения автокоммитации в блоке finally - вернуть его в состояние по умолчанию.Предположительно это сделано для того, чтобы снова использовать соединение.Тем не менее, это спорно, что это необходимо:.

  • Это почти ничего не стоит, чтобы включить автокоммит или отключить

На мой взгляд, последствия вышесказанного состоят в том, что есть два разумных способа справиться с этим:

  • Если все приложениенужны явные транзакции, отключите автокоммит при установлении соединения .... и оставьте его выключенным.

  • Если разные части приложения имеют разные требования автокоммитирования, то самый простой подход длякод, управляющий каждой транзакцией, чтобы установить для автоматической фиксации то, что ей нужно, затем не беспокоить сбросить ее.

5 или около того строк дополнительного кода для восстановления автоматической фиксации по умолчаниюсостояние в блоке finally не наносит мне удар по необходимости.В самом деле, если вы не можете гарантировать, что состояние автоматической фиксации всегда восстанавливается, лучше предположить, что состояние неопределенное;например, в начале метода updateCoffeeSales ... или в начале другого метода, который хочет включить автокоммит.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...