Это старый вопрос, но я хотел дать другое мнение по этому вопросу.
Производительность
Снижение производительности от транзакций зависит от механизма управления параллелизмом: обычно многоуровневое управление параллелизмом или блокировка. Озабоченность, выраженная в других ответах, по-видимому, связана со стоимостью завершения транзакции, но, по моему опыту, самая большая проблема - это длительные транзакции, которые могут стать причиной узких мест в производительности. Например, если СУБД использует блокировку, некоторые части таблицы не могут быть обновлены, пока транзакция с этой таблицей не будет завершена. Еще большее разочарование в таких системах, как Oracle, заключается в том, что операции DDL (ALTER TABLE
и т. Д.) Должны ждать, пока все транзакции, использующие эту таблицу, завершатся, что приведет к хлопотным тайм-аутам. Поэтому не думайте, что ваша транзакция не будет оштрафована, если вы просто используете SELECT
s.
Условные обозначения
Тонкая проблема с отключением режима автоматической фиксации состоит в том, что вы переходите от значения по умолчанию, поэтому все, кто работает с вашим кодом, могут этого не ожидать. действительно легко оставить случайный путь через функцию, который не заканчивается явным commit
или rollback
, и это может привести к непредсказуемому поведению в последующих вызываемых функциях. И наоборот, большая часть кода взаимодействия с БД, который я видел, содержит один оператор в каждой функции, для которого очень хорошо подходит поведение автоматической фиксации. Фактически, многие функции с несколькими утверждениями, с которыми я сталкивался, могли быть переписаны как отдельные операторы с немного большим ноу-хау в SQL - к сожалению, плохое приближение к объединениям, реализованным в Java, встречается довольно часто.
Мои личные предпочтения, основанные на разумном опыте, следующие для любых функций, выполняющих вызовы в базу данных:
- придерживаться стандартного поведения JDBC при автоматической фиксации;
- когда ваша функция включает в себя более одного оператора SQL, используйте явную транзакцию, задав
setAutocommit(false)
в начале каждой функции и вызвав commit()
(или rollback()
, если необходимо) в конце, а в идеале rollback()
в блоке catch
;
- принудительно применяет значение по умолчанию, помещая
setAutocommit(true)
в блок finally
, который упаковывает ваши вызовы JDBC в функцию (в отличие от таких API, как PHP / PDO, JDBC не сделает этого за вас после commit()
/ rollback()
);
- , если вы чувствуете дополнительную защиту, явно установите ваш выбор
setAutocommit(true)
или setAutocommit(false)
в начале каждой функции;