Какие уровни изоляции транзакций в SQL вы знаете и в чем их различия?

«Какие уровни изоляции транзакций в SQL вы знаете и в чем их различия?» — вопрос из категории Базы данных, который задают на 24% собеседований PHP Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Уровни изоляции транзакций определяют, насколько одна транзакция «видит» или изолирована от изменений, сделанных другими параллельными транзакциями. Они решают классические проблемы параллельного доступа. Уровни, от самого слабого к самому строгому:

1. READ UNCOMMITTED

  • Поведение: Транзакция может читать незафиксированные («грязные») данные из других транзакций.
  • Проблемы, которые возникают:
    • Грязное чтение (Dirty Read): Прочитали данные, которые потом откатятся.
    • Неповторяемое чтение.
    • Фантомное чтение.
  • Когда использовать: Практически никогда. Допустимо только для аналитических запросов, где точность не критична, а скорость важна.

2. READ COMMITTED

  • Поведение: Транзакция видит только зафиксированные данные. Это уровень по умолчанию в PostgreSQL и Oracle.
  • Решает: Грязное чтение.
  • Остаются проблемы:
    • Неповторяемое чтение (Non-repeatable Read): При повторном чтении одной и той же строки в рамках транзакции можно получить разные данные, если другая транзакция ее изменила и зафиксировала.
    • Фантомное чтение.
  • Реализация: Часто использует блокировки строк на время записи.

3. REPEATABLE READ

  • Поведение: Гарантирует, что строки, прочитанные один раз в транзакции, при повторном чтении останутся неизменными. Уровень по умолчанию в MySQL (InnoDB).
  • Решает: Грязное и неповторяемое чтение.
  • Остается проблема:
    • Фантомное чтение (Phantom Read): Появление новых строк, удовлетворяющих условию запроса, которые были добавлены другой зафиксированной транзакцией.
  • Реализация в InnoDB: Использует механизм многоверсионности (MVCC) и snapshot данных на начало транзакции.

4. SERIALIZABLE

  • Поведение: Самый строгий уровень. Транзакции выполняются так, как если бы они шли строго последовательно.
  • Решает: Все проблемы — грязное, неповторяемое и фантомное чтение.
  • Цена: Максимальные блокировки и потенциальное падение производительности из-за ожиданий.
  • Реализация: Может использовать блокировки диапазонов (range locks).

Пример на PostgreSQL:

-- Установка уровня изоляции для текущей транзакции
BEGIN TRANSACTION ISOLATION LEVEL REPEATABLE READ;

SELECT * FROM accounts WHERE user_id = 1;
-- ... некоторые операции ...
SELECT * FROM accounts WHERE user_id = 1; -- Данные будут теми же, даже если их изменили и закоммитили снаружи.

COMMIT;

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