В Spring, распространяется ли аннотация @Transactional с метода A на метод B, если B вызывается внутри A через другой бина?

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

Ответ

Нет, не распространяется. Spring AOP создает прокси-объекты для управления транзакциями. Вызов метода другого бина происходит через его прокси, минуя транзакционный контекст вызывающего метода.

Пример:

@Service
class ServiceA {
    @Transactional
    public void methodA() {
        // Этот вызов НЕ будет частью транзакции methodA
        serviceB.methodB();
    }
}

@Service
class ServiceB {
    // Без собственной @Transactional выполнится auto-commit
    public void methodB() {
        // Операции с БД
    }
}

Почему так происходит? Spring внедряет транзакционность через прокси, который перехватывает вызовы извне. Внутренние вызовы между бинами не перехватываются.

Решение:

  1. Добавить @Transactional на метод B.
  2. Использовать самовызов в одном классе (только если оба метода в одном бине):
    @Service
    class ServiceA {
        @Transactional
        public void methodA() {
            this.methodB(); // Будет в одной транзакции (режим прокси)
        }
        public void methodB() { /* ... */ }
    }

    Примечание: для самовызовов может потребоваться режим AspectJ вместо стандартного прокси.