Как работает вложенная @Transactional-аннотация, если внутренний метод находится в другом сервисе?

По умолчанию, если вызов происходит внутри одного класса (внутренний вызов метода), то прокси не перехватывает этот вызов, и новая транзакция не создаётся — используется текущая транзакция (если она есть).

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

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

В Java, при использовании транзакций (например, с аннотацией @Transactional в Spring), если внутри транзакционного метода вызывается другой метод, также помеченный как транзакционный, поведение зависит от типа прокси и настроек транзакций.

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

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

В Java, при использовании транзакций (например, с аннотацией @Transactional в Spring), если внутри транзакционного метода вызывается другой метод, также помеченный как транзакционный, поведение зависит от типа прокси и настроек транзакций.

По умолчанию, если вызов происходит внутри одного класса (внутренний вызов метода), то прокси не перехватывает этот вызов, и новая транзакция не создаётся — используется текущая транзакция (если она есть).

Если же вызов происходит извне (через прокси), то:

  • При propagation типа REQUIRED (по умолчанию) внутренняя транзакция не создаётся, используется существующая.
  • При propagation REQUIRES_NEW создаётся новая транзакция, приостанавливая текущую.

Таким образом, при вызове транзакционного метода из другого транзакционного метода в одном классе, как правило, используется одна и та же транзакция, и вложенная аннотация не создаёт новую транзакцию.

Если нужно, чтобы внутренний метод запускался в отдельной транзакции, вызов должен происходить через прокси (например, через другой бин или через self-инъекцию).

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

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

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

Подробнее