Какие существуют уровни изолированности транзакций?
Уровни изолированности транзакций — стандартизированные степени защиты от аномалий параллельного доступа. Чем выше уровень, тем сильнее изоляция, но ниже пропускная способность.
Уровни изолированности (SQL-стандарт)
| Уровень | Грязное чтение | Неповторяемое чтение | Фантомное чтение | Потерянное обновление |
|---|---|---|---|---|
| Read Uncommitted | Да | Да | Да | Нет |
| Read Committed | Нет | Да | Да | Нет |
| Repeatable Read | Нет | Нет | Да | Нет |
| Serializable | Нет | Нет | Нет | Нет |
Описание уровней
Read Uncommitted — транзакция видит незафиксированные изменения других транзакций. Самый слабый уровень, практически не используется.
Read Committed — транзакция видит только зафиксированные изменения других транзакций. Уровень по умолчанию в PostgreSQL и Oracle. При повторном чтении одной и той же строки значение может измениться, если другая транзакция успела зафиксироваться между чтениями.
Repeatable Read — при повторном чтении строки значение не меняется (создаётся снимок данных на момент начала транзакции). По стандарту допускает фантомные чтения, но в PostgreSQL фантомы тоже исключены на этом уровне за счёт SSI.
Serializable — результат параллельного выполнения транзакций эквивалентен их последовательному выполнению. Максимальная изоляция, минимальная производительность.
Уровни по умолчанию в популярных СУБД
| СУБД | Уровень по умолчанию | Реализация |
|---|---|---|
| PostgreSQL | Read Committed | MVCC (снимки) |
| MySQL (InnoDB) | Repeatable Read | MVCC + gap locks |
| Oracle | Read Committed | MVCC |
| SQL Server | Read Committed | Блокировки (или MVCC с RCSI) |
Настройка в SQL и Spring
Пример
-- SQL
SET TRANSACTION ISOLATION LEVEL REPEATABLE READ;
BEGIN;
-- ...
COMMIT;
Пример
// Spring
@Transactional(isolation = Isolation.REPEATABLE_READ)
public void processOrder(Long orderId) {
// ...
}
На собеседовании: интервьюер ожидает таблицу «уровень — допустимые аномалии» и понимание компромисса: выше изоляция — больше блокировок — ниже throughput. Частая ошибка — не знать уровень по умолчанию используемой СУБД (PostgreSQL — Read Committed, MySQL — Repeatable Read).