Какой уровень изоляции транзакций вы обычно используете в PostgreSQL и почему?

Ответ

Уровень изоляции по умолчанию в PostgreSQL — READ COMMITTED. В большинстве случаев я придерживаюсь его, так как он обеспечивает хороший баланс между согласованностью, производительностью и простотой понимания.

Сравнение уровней изоляции в PostgreSQL: Уровень Неповторяемое чтение Фантомное чтение Сериализация Производительность
READ COMMITTED (по умолчанию) Возможно Возможно Нет Высокая
REPEATABLE READ Запрещено Запрещено (в PG) Нет Средняя
SERIALIZABLE Запрещено Запрещено Гарантирована Низкая

Почему READ COMMITTED часто достаточно?

  1. Каждая инструкция в транзакции видит снимок данных, зафиксированный на момент ее начала. Это защищает от "грязного" чтения.
  2. Поведение предсказуемо и соответствует ожиданиям многих разработчиков.
  3. Конфликты сериализации редки в типичных веб-приложениях с короткими транзакциями.

Когда повышать уровень?

  • REPEATABLE READ: Когда в рамках одной транзакции критически важно несколько раз прочитать одни и те же строки и получить идентичный результат (например, сложные финансовые отчеты).
  • SERIALIZABLE: Для самых строгих требований, когда параллельное выполнение транзакций должно давать результат, идентичный их последовательному выполнению. Готовность обрабатывать ошибки SQLSTATE 40001 (serialization failure).

Пример установки уровня:

BEGIN;
SET TRANSACTION ISOLATION LEVEL REPEATABLE READ;
-- SELECT ... UPDATE ...
COMMIT;
-- Или на уровне соединения
ALTER DATABASE mydb SET default_transaction_isolation = 'REPEATABLE READ';

Выбор уровня — это всегда компромисс между целостностью данных и пропускной способностью.

Ответ 18+ 🔞

А, изоляция транзакций! Ну, классика, блядь. Слушай, тут как с выбором жены: можно взять строгую, которая будет следить за каждым чихом, но и ебать мозг постоянно, а можно — попроще, которая в основном норм, но иногда может и налево глянуть. PostgreSQL по умолчанию предлагает нам вариант попроще — READ COMMITTED. И знаешь что? В 90% случаев — это оно, золотая середина, ёпта.

Короче, табличка, чтобы не пиздеть много:

Уровень Неповторяемое чтение Фантомное чтение Сериализация Производительность
READ COMMITTED (дефолтный) Возможно, сука Возможно Нет Высокая, огонь
REPEATABLE READ Запрещено! Запрещено! (в PG — да, так-то!) Нет Средняя, терпимо
SERIALIZABLE Запрещено Запрещено Абсолютная, блядь! Низкая, тормознутая

Почему READ COMMITTED — наш бро?

  1. Грязные данные не увидит — это раз. Каждая команда смотрит на мир, который был, когда она началась. Не ахти какая свежесть, но уже не вчерашний суп.
  2. Поведение прямолинейное, как доска. Разработчик смотрит — и понимает, что происходит. Никаких ёбаных сюрпризов из параллельной вселенной.
  3. В обычных веб-приложениях, где транзакции — "пришёл-увидел-уебал-ушел", конфликты — редкость. Все живут дружно.

А когда надо напрячься и повысить градус?

  • REPEATABLE READ: Когда тебе в рамках одной транзакции надо десять раз прочитать одни и те же строчки и получить один и тот же результат. Типа, считаешь там баланс, а он у тебя между строчками изменился — вот это пиздец, особенно для финансовых отчётов. Этот уровень говорит: "Не, братан, что увидел в начале — то и будет, как вкопанное".
  • SERIALIZABLE: Это уже паранойя полная. "Ребята, давайте делать вид, что вы выполняетесь строго по очереди, один за другим, даже если вас тысяча". Результат — идеальный. Скорость — хуёвая. И будь готов, что транзакция может просто лбом об стену — SQLSTATE 40001 (serialization failure) — и сказать "пошла нахуй, я не могу так". Надо перезапускать.

Ну и как это впендюрить в код?

BEGIN;
SET TRANSACTION ISOLATION LEVEL REPEATABLE READ; -- Говорим "ща будет серьёзно"
-- SELECT ... UPDATE ...
COMMIT;
-- Или на всю базу сразу, если ты максималист
ALTER DATABASE mydb SET default_transaction_isolation = 'REPEATABLE READ';

Короче, выбор за тобой. Можно жить спокойно с READ COMMITTED и не париться, а можно включить режим "ядерной гарантии" с SERIALIZABLE и получить все прелести жизни в виде ошибок и тормозов. Как всегда, всё решает конкретная задача, а не мода, блядь.