В JDBC, когда автоматическая фиксация является ложью и никакими явными точками сохранения, были установлены, это хороший стиль или отходы для откатывания?

Скажите, что у Вас есть следующий код:

Connection conn;
try
{
   conn = ... // get connection
   conn.setAutoCommit(false);

   ... // Do some modification queries and logic

   conn.commit()
} catch(SQLException e)
{
    conn.rollback() // Do we need this?
    conn.close()
}

В этом коде, если существует исключение, это, лучше разрабатывают, чтобы просто закрыть соединение (так как автоматическая фиксация выключена), или явно откатывать и затем закрыть соединение? Нет никаких точек сохранения.

Я чувствую, что могло бы иметь смысл добавлять вызов отката потому что:

1) Кто-то, в будущем, мог бы добавить точки сохранения, но забыть добавлять откат

2) Это улучшает удобочитаемость

3) Это ничего не должно стоить, правильно?

Но очевидно, ни один из них не особенно востребован. Какая-либо общепринятая практика?

Примечание: Я знаю о потребности сделать, повторение пробует/завоевывает популярность закрыться и откат. У меня на самом деле есть промежуточное программное обеспечение, которое абстрагирует доступ к базе данных и заботится об этом, но я задавался вопросом, было ли добавление его лишним.

36
задан Uri 1 July 2010 в 21:13
поделиться

2 ответа

Закрытие должно откатиться, потому что оно не будет фиксироваться при освобождении ресурсов, но хорошо иметь конкретную обработку ошибок, поэтому, если вы хотите откатиться при исключении, сделайте это. Затем вы можете выполнить очистку в блоке finally {}. Rollback () происходит только в случае ошибки, и в этом случае ваша commit () не удалась или даже не была достигнута.

Connection conn = null;
try {
    conn = ...

    ...
    conn.commit();
}
catch (SQLException e) {
    if (conn != null) {
        conn.rollback();
    }
}
finally {
    if (conn != null) {
        conn.close();
    }
}
2
ответ дан 27 November 2019 в 06:07
поделиться

Обычная идиома следующая:

public void executeSomeQuery() throws SQLException {
    try (Connection connection = dataSource.getConnection()) {
        connection.setAutoCommit(false);

        try (PreparedStatement statement = connection.prepareStatement(SOME_SQL)) {
            // Fire transactional queries here.

            connection.commit();
        } catch (SQLException e) {
            connection.rollback();
            throw e;
        }
    }
}

Обратите внимание, что оператор try-with-resources Java 7 всегда неявно вызывает close () для ресурса при попытке Блок завершается, как если бы это произошло в finally .

Вызов rollback () также является обязательным, когда он касается объединенного соединения . А именно, он сбросит транзакционное состояние соединения. close () объединенного соединения этого не сделает, это будут делать только commit () и rollback () . Отсутствие вызова rollback () может привести к тому, что следующая аренда объединенного соединения все еще будет иметь (успешные) запросы предыдущей транзакции в своей памяти.

См. Также javadoc из Connection # close () (выделено не мной):

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

46
ответ дан 27 November 2019 в 06:07
поделиться
Другие вопросы по тегам:

Похожие вопросы: