Как работает `Propagation.NESTED` в транзакциях Spring?

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

Ответ

Propagation.NESTED — это вариант распространения транзакций в Spring, который создает вложенную транзакцию (nested transaction) на основе точек сохранения (savepoints) в текущей физической транзакции.

Принцип работы:

  1. Если активной транзакции нет, поведение аналогично Propagation.REQUIRED (создает новую).
  2. Если активная транзакция существует, метод выполняется внутри вложенной транзакции (устанавливается savepoint).
  3. Откат вложенной транзакции откатывает изменения только к этому savepoint, не затрагивая внешнюю транзакцию.
  4. Фиксация вложенной транзакции происходит условно — изменения фиксируются в БД только при успешной фиксации внешней транзакции.

Пример:

@Service
public class OrderService {
    @Transactional(propagation = Propagation.REQUIRED)
    public void processOrder(Order order) {
        // Основная логика заказа
        updateInventory(order); // Вложенная транзакция
        // Если здесь выбросится исключение, откатится ВСЁ (и inventory)
    }

    @Transactional(propagation = Propagation.NESTED)
    public void updateInventory(Order order) {
        // Логика обновления склада
        // Если здесь исключение, откатится ТОЛЬКО updateInventory,
        // но processOrder может продолжить обработку
    }
}

Ключевые ограничения и особенности:

  • Зависит от JDBC-драйвера: Работает только если драйвер БД (PostgreSQL, MySQL, Oracle и др.) поддерживает savepoints.
  • Не поддерживается JTA: Нельзя использовать с распределенными транзакциями (JTA).
  • Ограниченная поддержка в JPA: Поведение может отличаться. Для JPA предпочтительнее использовать отдельные транзакции (REQUIRES_NEW) или компенсирующие действия.
  • Использование: Полезен для сценариев, где часть бизнес-логики может безопасно откатиться независимо от основной операции.