Разбор влияния вложенных вызовов на транзакцию

При стандартном REQUIRED оба метода участвуют в одной транзакции. RuntimeException из doB помечает её rollback-only, даже если doA перехватил исключение.

Короткий ответ

Что ответить на собеседовании

При стандартном REQUIRED оба метода участвуют в одной транзакции. RuntimeException из doB помечает её rollback-only, даже если doA перехватил исключение.

Подробный разбор

Ответ с пояснениями

Условие

Контроллер инициирует вызов метода doA() из сервиса ServiceA. Какие изменения будут зафиксированы в базе данных?

@Service
public class ServiceA {

    @Autowired
    private ServiceB serviceB;

    @Transactional
    public void doA() {
        try {
            serviceB.doB();
        } catch (Exception ex) {

        }
    }
}

@Service
public class ServiceB {

    @Transactional
    public void doB() {
        if (true) {
            throw new IllegalStateException();
        }
    }
}

Ответ

При стандартном REQUIRED оба метода участвуют в одной транзакции. RuntimeException из doB помечает её rollback-only, даже если doA перехватил исключение.

При выходе из doA попытка commit приведёт к откату и обычно UnexpectedRollbackException. В показанном коде операций записи вообще нет, поэтому никакие изменения не фиксируются. Если бы записи были до ошибки, они откатились бы вместе с общей транзакцией. Результат предполагает вызовы через работающие Spring-прокси и обычные настройки rollback. REQUIRES_NEW у doB создал бы отдельную транзакцию с другим поведением, но это бизнес-решение, а не способ скрыть ошибку.

ИИ-помощник для собеседований

Хочешь уверенно проходить собеседования?

Попробуй ИИ-помощник для собеседований: слышит вас и собеседника, анализирует экран, подсказывает ответы в реальном времени, работает без VPN и не попадает в захват экрана.

Подробнее