Вопрос проверяет понимание внутренних механизмов Spring AOP и того, как именно применяется @Transactional во время выполнения кода.
Spring реализует транзакции с помощью прокси-объектов. Вместо прямого вызова метода вызывается прокси, который оборачивает выполнение логикой транзакции. Прокси открывает транзакцию перед вызовом метода и коммитит или откатывает её после. Если метод вызывается в обход прокси, транзакция не создаётся. Поэтому важно понимать, как именно происходит вызов метода.
Spring не «вшивает» транзакции прямо в код метода. Вместо этого он использует механизм прокси и AOP.
Прокси в Spring — это объект-обёртка над бином, который перехватывает вызовы методов и добавляет дополнительное поведение, например управление транзакциями.
Перед тем как метод будет выполнен, управление перехватывает прокси.
Spring находит бин с @Transactional
Создаёт прокси-объект
JDK dynamic proxy, если есть интерфейс
CGLIB proxy, если интерфейса нет
Когда другой бин вызывает метод:
Вызов идёт через прокси
Прокси:
открывает транзакцию
вызывает реальный метод
делает commit или rollback
Spring связывает транзакцию с текущим потоком выполнения.
Это позволяет
не передавать транзакцию вручную
прозрачно использовать её в DAO-слое
Прокси работает только для public-методов
Вызов должен происходить извне бина
Самовызовы (self-invocation) прокси не перехватывает
Клиент → прокси
Прокси → целевой метод
Прокси управляет транзакцией
Транзакции в Spring работают за счёт прокси и AOP. Если метод вызывается в обход прокси, аннотация @Transactional не сработает.