Зачем существует несколько уровней изоляции транзакций в SQL?

«Зачем существует несколько уровней изоляции транзакций в SQL?» — вопрос из категории Базы данных, который задают на 10% собеседований Java Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Уровни изоляции существуют для компромисса между согласованностью данных (ACID) и производительностью (параллелизмом). Разные приложения имеют разные требования: финансовым системам нужна максимальная целостность, аналитическим отчетам — высокая скорость чтения.

Уровни изоляции (от самого слабого к строгому) и их компромиссы:

Уровень Грязное чтение Неповторяющееся чтение Фантомное чтение Производительность
READ UNCOMMITTED ❌ Возможно ❌ Возможно ❌ Возможно 🟢 Высокая
READ COMMITTED ✅ Защита ❌ Возможно ❌ Возможно 🟡 Средняя
REPEATABLE READ ✅ Защита ✅ Защита ❌ Возможно 🟡 Средняя
SERIALIZABLE ✅ Защита ✅ Защита ✅ Защита 🔴 Низкая

Почему важен выбор:

  • READ COMMITTED — наиболее распространенный баланс. Защищает от чтения "грязных" (незафиксированных) данных, что критично для большинства операций.
  • REPEATABLE READ — нужен для операций, где значение должно оставаться неизменным между двумя чтениями (например, проверка баланса перед списанием).
  • SERIALIZABLE — обеспечивает полную изоляцию, но за счет серьезных блокировок и риска таймаутов. Используется для критичных финансовых транзакций.

Пример выбора в Spring:

@Service
public class TransferService {
    @Transactional(isolation = Isolation.REPEATABLE_READ) // Гарантия для read-modify-write
    public void transferMoney(Long fromId, Long toId, BigDecimal amount) {
        // 1. SELECT баланс (блокировка строки)
        // 2. Проверка достаточности средств
        // 3. UPDATE балансов
    }
}