Autocommit
Если вы работали с JDBC (интерфейс к базам данных в Джаве), то наверняка видели
свойство autoCommit. Точное его описание – камень в ботинке: вроде бы
маленький, но измотает всю душу.
Поведение его следующее. Когда autoCommit — истина, запросы выполняются без
явных транзакций. Например, вызываешь UPDATE, и изменения вступают в силу тут
же. Если нужна транзакция, явно прописываешь BEGIN и COMMIT. Когда
autoCommit ложь, то все интересней. Если в текущий момент транзакции нет, то
любой запрос откроет ее. Далее все запросы будут выполняться в транзакции, пока
мы не вызовем COMMIT.
Спрашивается, какое значение у autoCommit по умолчанию? Ответ — истина, но
путаницы все равно хватает. Тысячи людей погорели на том, что вызывают INSERT,
смотрят в базу – а там фига с маслом. Оказывается, autoCommit был ложью, и
перед вызовом UPDATE сработал неявный BEGIN. В конце мы не вызвали COMMIT,
транзакция не закрылась, изменения откатились.
Многие джависты думают, что autoCommit – часть базы данных. И очень
удивляются, узнав, что это не так. База данных ничего не знает ни о каком
autoCommit. Этого свойства нет в протоколе Postgres, нет его и в протоколах
других баз. Во всех случаях он имитируется логическом флагом и бородой
if-else. Причем если вы думаете, что все просто, то ошибаетесь: на уровне
драйвера проверка на autoCommit случается часто. Скажем, при входе в транзакцию
нужно запоминать его прошлое значение и потом восстанавливать. При смене
autoCommit надо проверять, находимся ли мы в транзакции и если да, завершать
ее. И все это – ради чего?
Я согласен, что, возможно, какая-то бородатая база вроде IBM DB2 на мейнфреймах поддерживала autoCommit на уровне протокола. Но сегодня это рудимент вроде лишнего позвонка, который когда-то был хвостом. В современных драйверах autoCommit имитируется программно, при этом нет способа избежать его вообще.
К тысяче людей, погоревших на autoCommit, присоединился и я. При этом дело
было не на Джаве, а в Питоне с библиотекой psycopg2. Все по классике: скрипт
подключается к базе и делает UPDATE. Проверяю базу — изменений нет. Оказалось,
в psycopg2 слизали autoCommit с JDBC, и по умолчанию он выключен.
Слушайте, хватит уже! Перестаньте тянуть в библиотеки это старье. Опирайтесь на
естественное поведение базы: либо каждый запрос выполняется в неявной
транзакции, либо их несколько заключаются в транзакцию. В современных
библиотеках никаких autoCommit нет, и слава богу. AutoCommit – это древнейший
рудимент из пещерных времен. И в отличие от лишнего позвонка, он колоссально
мешает жить.
Нашли ошибку? Выделите мышкой и нажмите Ctrl/⌘+Enter