Вопрос проверяет знание ограничений прокси-механизма Spring и типичную ловушку при работе с @Transactional.
Транзакция не будет создана вообще. Вызов метода внутри того же класса происходит напрямую, минуя прокси. Spring не перехватывает такой вызов. В результате @Transactional просто игнорируется. Это частая ошибка у начинающих разработчиков.
На первый взгляд кажется логичным, что при вызове одного метода из другого в том же классе транзакция должна работать. Но из-за прокси-механизма это не так.
Self-invocation — это вызов метода бина из другого метода того же бина напрямую, без прохождения через Spring-прокси.
Spring создаёт:
реальный объект класса
прокси-объект поверх него
Когда метод вызывает другой метод того же класса:
вызов идёт напрямую (this.method())
прокси не участвует
транзакционная логика не применяется
@Service
public class UserService {
public void outer() {
inner(); // транзакции не будет
}
@Transactional
public void inner() {
// ожидалась транзакция, но её нет
}
}
Прокси перехватывает только внешние вызовы
Внутренние вызовы неотличимы от обычных методов Java
Это компромисс архитектуры AOP в Spring
Вынести транзакционный метод в другой бин
Вызывать метод через другой сервис
Использовать более сложные AOP-настройки (редко)
При вызове транзакционного метода внутри того же класса транзакция не создаётся, потому что вызов не проходит через прокси.