Что такое уровни изоляции транзакций в Spring (@Transactional) и зачем они нужны?

«Что такое уровни изоляции транзакций в Spring (@Transactional) и зачем они нужны?» — вопрос из категории Spring, который задают на 10% собеседований Java Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Уровень изоляции транзакции определяет, насколько одна транзакция изолирована от изменений, сделанных другими параллельными транзакциями. Он нужен для баланса между целостностью данных и производительностью.

Проблемы, которые предотвращают уровни изоляции:

  1. «Грязное» чтение (Dirty Read): Чтение незафиксированных данных другой транзакции, которые могут быть откатаны.
  2. Неповторяющееся чтение (Non-repeatable Read): Получение разных значений одной и той же строки при повторном чтении в рамках одной транзакции из-за коммита другой транзакции.
  3. Фантомное чтение (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 используется редко, только для критически важных данных из-за серьёзного падения производительности.