Ответ
Уровень изоляции транзакции определяет, насколько одна транзакция изолирована от изменений, сделанных другими параллельными транзакциями. Он нужен для баланса между целостностью данных и производительностью.
Проблемы, которые предотвращают уровни изоляции:
- «Грязное» чтение (Dirty Read): Чтение незафиксированных данных другой транзакции, которые могут быть откатаны.
- Неповторяющееся чтение (Non-repeatable Read): Получение разных значений одной и той же строки при повторном чтении в рамках одной транзакции из-за коммита другой транзакции.
- Фантомное чтение (Phantom Read): Появление новых строк (фантомов) при повторном выполнении одного и того же запроса из-за коммита другой транзакции.
Уровни изоляции в Spring (от наименее строгого к наиболее строгому):
Уровень (Isolation.) |
Dirty Read | Non-repeatable Read | Phantom Read | Производительность |
|---|---|---|---|---|
READ_UNCOMMITTED |
❌ Возможно | ❌ Возможно | ❌ Возможно | Высокая |
READ_COMMITTED (часто по умолчанию) |
✅ Запрещено | ❌ Возможно | ❌ Возможно | Средняя |
REPEATABLE_READ |
✅ Запрещено | ✅ Запрещено | ❌ Возможно | Низкая |
SERIALIZABLE |
✅ Запрещено | ✅ Запрещено | ✅ Запрещено | Очень низкая |
Пример настройки в Spring:
@Service
public class BankService {
@Transactional(isolation = Isolation.READ_COMMITTED) // Гарантирует чтение только закоммиченных данных
public void transferMoney(Long fromAcc, Long toAcc, BigDecimal amount) {
// Логика перевода
}
}
Выбор уровня: READ_COMMITTED — хороший баланс для большинства приложений. SERIALIZABLE используется редко, только для критически важных данных из-за серьёзного падения производительности.