Как выбрать уровень изоляции транзакции в SQL?

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

Ответ

Уровень изоляции определяет, какие аномалии чтения (dirty read, non-repeatable read, phantom read) допустимы. Выбор зависит от компромисса между согласованностью данных и производительностью/параллелизмом.

Уровень изоляции Грязное чтение Неповторяющееся чтение Фантомное чтение Сценарий использования
READ UNCOMMITTED Да Да Да Аналитика, агрегация, где допустима временная несогласованность. Максимальная производительность.
READ COMMITTED Нет Да Да Стандартный выбор для большинства OLTP-систем. Баланс между согласованностью и производительностью.
REPEATABLE READ Нет Нет Да Операции, требующие согласованности набора данных в рамках одной транзакции (например, проверка баланса перед списанием).
SERIALIZABLE Нет Нет Нет Критически важные операции, где аномалии недопустимы (финансовые переводы, бронирование). Минимальный параллелизм.

Пример настройки в Spring (@Transactional):

import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Transactional;

// Для критичной финансовой операции
@Transactional(isolation = Isolation.SERIALIZABLE)
public void executeAtomicTransfer(Long fromAcc, Long toAcc, BigDecimal amount) {
    // ... логика перевода
}

// Для обычного чтения данных
@Transactional(isolation = Isolation.READ_COMMITTED)
public BigDecimal getAccountBalance(Long accountId) {
    // ... чтение баланса
}

Важно: Фактическое поведение может отличаться в зависимости от СУБД (например, в InnoDB REPEATABLE READ также предотвращает некоторые фантомные чтения).