Ответ
Поведение зависит от распространения транзакций (Propagation). Ключевые сценарии:
1. Вложенная транзакция с SAVEPOINT (Propagation.NESTED)
- Внешняя транзакция приостанавливается, для вложенной создается точка сохранения (savepoint).
- При ошибке во вложенной: откатывается только до savepoint, внешняя транзакция продолжает работу.
- Поддерживается не всеми СУБД (например, работает в H2, но не в MySQL с InnoDB).
2. Независимая новая транзакция (Propagation.REQUIRES_NEW)
- Внешняя транзакция приостанавливается, запускается полностью новая, независимая транзакция.
- При ошибке во вложенной: откатывается только новая транзакция. Внешняя транзакция возобновляется и может быть зафиксирована или откатана отдельно.
@Transactional public void outerMethod() { // Внешняя транзакция T1 someRepository.save(entityA); try { innerMethod(); // Запускает T2, T1 приостановлена } catch (Exception e) { // T2 откатилась, T1 продолжается } // T1 может быть зафиксирована }
@Transactional(propagation = Propagation.REQUIRES_NEW) public void innerMethod() { // Новая независимая транзакция T2 someRepository.save(entityB); throw new RuntimeException("Rollback T2 only"); }
**3. Общая транзакция (Propagation.REQUIRED — по умолчанию)**
* Метод выполняется в существующей внешней транзакции.
* **Любая неперехваченная RuntimeException** приводит к откату **всей** единой транзакции.
**Вывод:** Используйте `REQUIRES_NEW` для изоляции критических операций, а `NESTED` — для частичных откатов, если СУБД поддерживает.