Ответ
Уровни изоляции транзакций определяют, насколько транзакции изолированы друг от друга, балансируя между целостностью данных и производительностью. Стандарт SQL определяет четыре уровня (от самого слабого к самому строгому).
Уровни изоляции и решаемые аномалии
| Уровень | Грязное чтение (Dirty Read) | Неповторяющееся чтение (Non-repeatable Read) | Фантомное чтение (Phantom Read) |
|---|---|---|---|
| READ UNCOMMITTED | ❌ Возможно | ❌ Возможно | ❌ Возможно |
| READ COMMITTED | ✅ Решено | ❌ Возможно | ❌ Возможно |
| REPEATABLE READ | ✅ Решено | ✅ Решено | ❌ Возможно |
| SERIALIZABLE | ✅ Решено | ✅ Решено | ✅ Решено |
Описание уровней
-
READ UNCOMMITTED
- Транзакция видит незафиксированные изменения других транзакций.
- Проблема: Грязное чтение — можно прочитать данные, которые потом будут откачены.
- Использование: Редко, в сценариях, где важна максимальная скорость, а целостность данных второстепенна.
-
READ COMMITTED
- Транзакция видит только зафиксированные данные других транзакций. Это уровень по умолчанию в PostgreSQL и Oracle.
- Проблема: Неповторяющееся чтение — повторное чтение одной строки в рамках транзакции может вернуть разные данные, если другая транзакция изменила и зафиксировала эту строку.
-
REPEATABLE READ
- Гарантирует, что строки, прочитанные один раз в транзакции, не изменятся другими транзакциями до её завершения. Это уровень по умолчанию в MySQL (InnoDB).
- Проблема: Фантомное чтение — появление новых строк, удовлетворяющих условию запроса, из-за вставок другими транзакциями.
-
SERIALIZABLE
- Самый строгий уровень. Гарантирует полную изоляцию, как если бы транзакции выполнялись последовательно.
- Достигается блокировками или управлением версиями данных (MVCC).
- Недостаток: Наибольшее влияние на производительность и параллелизм.
Пример настройки в JDBC
Connection connection = dataSource.getConnection();
// Установка уровня изоляции для текущего соединения
connection.setTransactionIsolation(Connection.TRANSACTION_REPEATABLE_READ);
// Или при старте транзакции
connection.setAutoCommit(false);