Какие уровни изоляции транзакций определены в стандарте SQL?

Ответ

Стандарт SQL (ANSI/ISO) определяет четыре уровня изоляции транзакций, которые контролируют видимость изменений, сделанных в параллельных транзакциях. Они представляют собой компромисс между согласованностью данных и производительностью.

Уровни перечислены от наименее строгого к наиболее строгому, и каждый последующий уровень предотвращает определенные аномалии:

  1. READ UNCOMMITTED:

    • Описание: Транзакция может читать данные, которые были изменены другой транзакцией, но еще не зафиксированы.
    • Разрешенные аномалии: Грязное чтение (Dirty Read), Неповторяющееся чтение (Non-repeatable Read), Фантомное чтение (Phantom Read).
    • На практике: Я практически никогда не использую этот уровень из-за риска чтения невалидных данных.
  2. READ COMMITTED:

    • Описание: Транзакция видит только зафиксированные данные других транзакций. Это уровень по умолчанию в PostgreSQL и Oracle.
    • Предотвращает: Грязное чтение.
    • Разрешенные аномалии: Неповторяющееся чтение, Фантомное чтение.
    • Как работает: При повторном чтении одной и той же строки в рамках транзакции можно получить разные данные, если другая транзакция зафиксировала изменения этой строки.
  3. REPEATABLE READ:

    • Описание: Гарантирует, что любые строки, прочитанные в течение транзакции, будут оставаться неизменными до ее завершения. Другие транзакции не могут изменять или удалять эти строки.
    • Предотвращает: Грязное чтение, Неповторяющееся чтение.
    • Разрешенные аномалии: Фантомное чтение (хотя в некоторых СУБД, например, в MySQL/InnoDB и PostgreSQL, фантомы также предотвращаются на этом уровне).
    • Уровень по умолчанию в MySQL (InnoDB).
  4. SERIALIZABLE:

    • Описание: Самый строгий уровень. Результат параллельного выполнения набора сериализуемых транзакций должен быть идентичен результату их последовательного выполнения.
    • Предотвращает: Все аномалии: Грязное чтение, Неповторяющееся чтение, Фантомное чтение.
    • На практике: Обеспечивает полную изоляцию, но за счет максимальных накладных расходов (блокировок или управления версиями), что может сильно снизить пропускную способность. Я использую его только для критических операций, где абсолютная согласованность важнее производительности.

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

-- Установка уровня для текущей транзакции
BEGIN TRANSACTION ISOLATION LEVEL REPEATABLE READ;
-- Операции SELECT, UPDATE, DELETE...
COMMIT;

-- Установка уровня по умолчанию для сессии
SET SESSION CHARACTERISTICS AS TRANSACTION ISOLATION LEVEL READ COMMITTED;

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

Ответ 18+ 🔞

А, ну это про транзакции, ебать мои старые костыли! Слушай, тут всё просто, как три копейки, но если накосячить — будет вам хиросима и нигерсраки в базе данных, вот честно.

Короче, стандарт SQL, этот хитрожопый, придумал четыре уровня, как транзакции друг друга видят. И это, блядь, вечный компромисс: либо у тебя всё чётко и согласованно, но медленно, либо быстро, но можно начитаться такого, что сам от себя охуеешь.

Идут они, как в армии, от самого распиздайского до строгого, как мой дед. Запоминай:

  1. READ UNCOMMITTED (Чтение незафиксированного)

    • Суть: Твоя транзакция может подсматривать за другим чуваком, который ещё даже не закончил свою работу и не сказал "окей, сохраняю". Представь, читаешь ты черновик, который автор ещё может выкинуть в урну.
    • Что может пойти не так? Да всё, блядь! Грязные чтения, неповторяющиеся чтения, фантомы — полный набор ужастиков. Читаешь одно, а через секунду это уже не существует. Удивление пиздец.
    • На практике: Я этот уровень, честно, в рот меня чих-пых, почти никогда не трогаю. Это как брать еду из мусорки — вроде можно, но зачем, если есть нормальный магазин? Доверия к таким данным — ноль ебать.
  2. READ COMMITTED (Чтение зафиксированного)

    • Суть: А вот это уже адекватнее. Ты видишь только то, что другие ребята уже окончательно сохранили и подписали. Никаких черновиков. По дефолту стоит в Постгресе и Оракуле, не просто так.
    • Что ловит: Грязные чтения отшивает нахуй. Ты не прочитаешь недоделанную хуйню.
    • Но есть нюанс: Неповторяющееся чтение и фантомы ещё могут быть. То есть, прочитал ты значение в начале транзакции, потом через минуту перечитал — а там уже другое, потому что кто-то между делом успел закоммитить изменения. Подозрение ебать чувствую, когда на этом уровне работаю.
  3. REPEATABLE READ (Повторяемое чтение)

    • Суть: Вот тут уже серьёзнее. Если ты что-то прочитал в рамках своей транзакции, то эти данные замораживаются для тебя. Никто другой не может их изменить или удалить, пока ты не закончишь. Как будто сфоткал.
    • Что ловит: Грязные чтения и неповторяющиеся чтения — на хуй.
    • Призраки: В теории могут проскочить фантомные строки (новые данные, которых раньше не было). Но, ёпта, современные СУБД вроде MySQL/InnoDB и PostgreSQL такие хитрожопые, что часто и фантомов не пропускают на этом уровне. В MySQL это вообще уровень по умолчанию.
  4. SERIALIZABLE (Сериализуемый)

    • Суть: Царь-уровень, блядь. Полная изоляция. Представь, что все транзакции выстроились в очередь и выполняются строго по одной, как в совковом магазине. Никаких спецэффектов, чистая математика.
    • Что ловит: Всё. Все аномалии. Грязь, нестабильность, фантомы — всё к ебене матери.
    • Цена: Овердохуища накладных расходов. База будет всё блокировать или версии считать, и производительность может накрыться медным тазом. Используй только для самых критичных операций, где ошибка стоит дороже, чем твоё терпение (а терпения, я смотрю, ноль ебать).

Ну и как это впихнуть в код, например, в PostgreSQL:

-- Ставим уровень для конкретной транзакции
BEGIN TRANSACTION ISOLATION LEVEL REPEATABLE READ;
-- Дальше делаешь свои дела: SELECT, UPDATE...
COMMIT;

-- Или можешь для всей сессии по умолчанию настроить
SET SESSION CHARACTERISTICS AS TRANSACTION ISOLATION LEVEL READ COMMITTED;

Короче, выбирай с умом. Если пишешь что-то простое — READ COMMITTED хватит за глаза. Если денежные переводы или инвентаризацию — задумайся о REPEATABLE READ или даже SERIALIZABLE. Главное — понимать, на каком тонком льду ты ходишь, когда ослабляешь изоляцию.

Видео-ответы