Что вы знаете об уровнях изоляции транзакций в MySQL?

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

Ответ

Уровни изоляции транзакций определяют, насколько изменения в одной транзакции видны другим параллельным транзакциям, и какие аномалии чтения они предотвращают. В MySQL InnoDB поддерживаются четыре стандартных уровня:

  1. READ UNCOMMITTED: Самый низкий уровень. Возможно «грязное чтение» — транзакция видит незафиксированные изменения другой транзакции.
  2. READ COMMITTED: Транзакция видит только зафиксированные данные. Предотвращает грязное чтение, но возможны «неповторяющееся чтение» (одна и та же строка, прочитанная дважды, может измениться) и «фантомное чтение» (появление новых строк).
  3. REPEATABLE READ (уровень по умолчанию для InnoDB): Гарантирует, что данные, прочитанные в течение транзакции, не изменятся. Предотвращает грязное и неповторяющееся чтение. InnoDB также предотвращает фантомное чтение за счёт механизма gap-блокировок.
  4. SERIALIZABLE: Самый строгий уровень. Транзакции изолируются полностью, как если бы выполнялись последовательно. Достигается за счёт блокировок на чтение.

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

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

START TRANSACTION;
SELECT * FROM orders WHERE user_id = 100; -- Этот «снимок» данных будет неизменным до конца транзакции
-- ... некоторая логика ...
COMMIT;

На практике чаще всего работаю с уровнем по умолчанию REPEATABLE READ, так как он обеспечивает хороший баланс между согласованностью и производительностью для большинства задач.