Ответ
Уровни изоляции транзакций определяют, насколько изменения в одной транзакции видны другим параллельным транзакциям, и какие аномалии чтения они предотвращают. В MySQL InnoDB поддерживаются четыре стандартных уровня:
- READ UNCOMMITTED: Самый низкий уровень. Возможно «грязное чтение» — транзакция видит незафиксированные изменения другой транзакции.
- READ COMMITTED: Транзакция видит только зафиксированные данные. Предотвращает грязное чтение, но возможны «неповторяющееся чтение» (одна и та же строка, прочитанная дважды, может измениться) и «фантомное чтение» (появление новых строк).
- REPEATABLE READ (уровень по умолчанию для InnoDB): Гарантирует, что данные, прочитанные в течение транзакции, не изменятся. Предотвращает грязное и неповторяющееся чтение. InnoDB также предотвращает фантомное чтение за счёт механизма gap-блокировок.
- SERIALIZABLE: Самый строгий уровень. Транзакции изолируются полностью, как если бы выполнялись последовательно. Достигается за счёт блокировок на чтение.
Пример установки уровня:
-- Устанавливаем уровень изоляции для текущей сессии
SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ;
START TRANSACTION;
SELECT * FROM orders WHERE user_id = 100; -- Этот «снимок» данных будет неизменным до конца транзакции
-- ... некоторая логика ...
COMMIT;
На практике чаще всего работаю с уровнем по умолчанию REPEATABLE READ, так как он обеспечивает хороший баланс между согласованностью и производительностью для большинства задач.