Можно ли управлять транзакциями программно в Spring?

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

Ответ

Да, Spring предоставляет API для программного управления транзакциями. Это альтернатива декларативному подходу с аннотацией @Transactional и используется, когда нужен детальный контроль над границами транзакции.

Основные способы:

  1. Использование TransactionTemplate (рекомендуемый, более высокоуровневый):

    @Autowired
    private TransactionTemplate transactionTemplate;
    
    public Object executeInTransaction() {
        return transactionTemplate.execute(status -> {
            // Бизнес-логика внутри транзакции
            someRepository.save(entity);
            return "Результат";
        }); // Транзакция фиксируется автоматически при успехе
    }
  2. Использование PlatformTransactionManager (низкоуровневый):

    @Autowired
    private PlatformTransactionManager transactionManager;
    
    public void executeWithManualControl() {
        // Определяем параметры транзакции (изоляция, propagation и т.д.)
        DefaultTransactionDefinition def = new DefaultTransactionDefinition();
        def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
    
        // Начинаем транзакцию
        TransactionStatus status = transactionManager.getTransaction(def);
    
        try {
            // Бизнес-логика
            someService.process();
            // Фиксация транзакции
            transactionManager.commit(status);
        } catch (Exception e) {
            // Откат транзакции
            transactionManager.rollback(status);
            throw e;
        }
    }

Когда использовать программное управление?

  • Когда границы транзакции должны определяться динамически, по условию.
  • При необходимости управления несколькими независимыми транзакциями в одном методе.
  • В коде, где использование AOP (как в @Transactional) затруднено (например, в @PostConstruct).

Недостаток: Программный подход приводит к загромождению бизнес-кода инфраструктурной логикой. Декларативный подход (@Transactional) обычно предпочтительнее.