Что такое Propagation.NESTED в Spring?

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

Ответ

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

Ключевое поведение:

  • Если внешняя транзакция откатывается, откатывается и вся вложенная.
  • Если вложенная транзакция откатывается (и исключение перехвачено), внешняя транзакция может продолжить работу с точки сохранения, созданной до начала вложенной.

Важные ограничения:

  • Работает только с JDBC-драйверами, поддерживающими savepoints (например, PostgreSQL, H2, MySQL с InnoDB).
  • Не работает с JTA-менеджерами транзакций (JTA).

Пример использования:

@Service
public class OrderService {
    @Transactional(propagation = Propagation.REQUIRED)
    public void processOrder(Order order) {
        // Основная логика заказа
        saveOrder(order);
        try {
            processPayment(order); // Вложенная транзакция
        } catch (PaymentFailedException e) {
            // Откат ТОЛЬКО операций payment, order сохраняется
            log.error("Payment failed, order kept", e);
        }
        // Внешняя транзакция продолжается
    }

    @Transactional(propagation = Propagation.NESTED)
    public void processPayment(Order order) {
        // Логика платежа, которая может откатиться независимо
        paymentGateway.charge(order);
    }
}

Сравнение с REQUIRES_NEW:

  • REQUIRES_NEW: Создает полностью новую, независимую физическую транзакцию. Приостанавливает внешнюю.
  • NESTED: Использует точку сохранения в рамках одной физической транзакции. Более легковесна, но зависит от поддержки СУБД.