Что такое распространение транзакций (Transaction Propagation) в Spring?

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

Ответ

Transaction Propagation определяет границы транзакции при вызове одного @Transactional-метода из другого. Это политика, управляющая тем, как должен вести себя метод: использовать существующую транзакцию, создать новую или работать без неё.

Типы распространения (Propagation.*):

  • REQUIRED (по умолчанию) – Использует активную транзакцию, если она есть. Если нет – создаёт новую.
  • REQUIRES_NEW – Всегда создаёт новую, независимую транзакцию. Текущая транзакция приостанавливается.
  • SUPPORTS – Работает в контексте существующей транзакции, если она есть. Если нет – выполняется без транзакции.
  • NOT_SUPPORTED – Выполняется без транзакции. Активная транзакция приостанавливается на время работы метода.
  • MANDATORY – Требует активной транзакции. Если её нет – выбрасывается исключение IllegalTransactionStateException.
  • NEVER – Запрещает выполнение в транзакции. Если активная транзакция существует – выбрасывается исключение.
  • NESTED – Создаёт вложенную транзакцию (точку сохранения) внутри существующей, если она есть. Откат вложенной транзакции не приводит к откату внешней. Поддерживается не всеми менеджерами транзакций (например, работает с DataSourceTransactionManager).

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

@Service
public class UserService {
    @Transactional(propagation = Propagation.REQUIRED)
    public void createUser(User user) {
        // Использует или создаёт транзакцию
        userRepository.save(user);
        updateAuditLog(user); // Вызов метода с другой политикой
    }

    @Transactional(propagation = Propagation.REQUIRES_NEW)
    public void updateAuditLog(User user) {
        // Всегда выполняется в новой, независимой транзакции
        auditLogRepository.save(new AuditLog("USER_CREATED", user.getId()));
    }
}

Почему это важно: Правильный выбор политики предотвращает непредсказуемое поведение (например, откат всей бизнес-операции из-за исключения в логгировании) и управляет изоляцией операций.