Что такое TransactionTemplate в Spring и в каких случаях его применяют?

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

Ответ

TransactionTemplate — это класс в Spring, предоставляющий программный (declarative) способ управления транзакциями. Он является альтернативой декларативному управлению через @Transactional и даёт больше контроля над границами транзакции.

Когда использовать?

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

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

@Service
public class TransferService {
    private final TransactionTemplate transactionTemplate;

    public TransferService(PlatformTransactionManager transactionManager) {
        this.transactionTemplate = new TransactionTemplate(transactionManager);
        // Настройка параметров транзакции
        this.transactionTemplate.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
        this.transactionTemplate.setIsolationLevel(TransactionDefinition.ISOLATION_READ_COMMITTED);
    }

    public void transferMoney(Long fromAccId, Long toAccId, BigDecimal amount) {
        // Код внутри execute() выполняется в транзакции
        transactionTemplate.execute(status -> {
            Account from = accountRepository.findById(fromAccId).orElseThrow();
            Account to = accountRepository.findById(toAccId).orElseThrow();

            from.debit(amount);
            to.credit(amount);

            accountRepository.save(from);
            accountRepository.save(to);

            // Принудительный откат по условию
            if (someCondition) {
                status.setRollbackOnly();
            }

            return "Transfer completed"; // Возвращаемое значение
        }); // Автоматический commit/rollback
    }
}

Преимущества перед @Transactional:

  • Точный контроль: Границы транзакции чётко видны в коде.
  • Гибкость: Возможность динамически менять параметры (изоляция, распространение).
  • Условный rollback: Легко вызвать status.setRollbackOnly() в любом месте.

Недостаток: Код становится более многословным по сравнению с аннотацией @Transactional.