Ответ
Уровни изоляции транзакций определяют, насколько одна транзакция «видит» или изолирована от изменений, сделанных другими параллельными транзакциями. Они решают классические проблемы параллельного доступа. Уровни, от самого слабого к самому строгому:
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;
Выбор уровня — это компромисс между целостностью данных и производительностью/масштабируемостью.