Ответ
Да, Spring предоставляет API для программного управления транзакциями. Это альтернатива декларативному подходу с аннотацией @Transactional и используется, когда нужен детальный контроль над границами транзакции.
Основные способы:
-
Использование
TransactionTemplate(рекомендуемый, более высокоуровневый):@Autowired private TransactionTemplate transactionTemplate; public Object executeInTransaction() { return transactionTemplate.execute(status -> { // Бизнес-логика внутри транзакции someRepository.save(entity); return "Результат"; }); // Транзакция фиксируется автоматически при успехе } -
Использование
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) обычно предпочтительнее.