Пожалуйста go по ссылке Документация
На следующих изображениях показан концептуальный вид вызова метода на транзакционном прокси:
Теперь с этой информацией метод, отмеченный @Transactional
, начнет транзакцию только тогда, когда вызов метода поступит через прокси-объект класса, который имеет этот аннотированный метод. Этот вызов упоминается экспертами в вашем предыдущем вопросе как внешний вызов .
В случае вашего примера
Реализация абстрактного метода AbstractUserDetailsAuthenticationProvider. retrieveUser () вызывается из AbstractUserDetailsAuthenticationProvider.authenticate () , который является самостоятельным вызовом. Это то, что эксперты называют внутренний звонок . Также обратите внимание, что метод authenticate()
не является @Transactional
Go в документации по разделу Использование транзакций
В режиме прокси (который по умолчанию), только внешние вызовы методов, поступающие через прокси, перехватываются. Это означает, что самовывоз (по сути, метод в целевом объекте, вызывающий другой метод целевого объекта) не приводит к фактической транзакции во время выполнения, даже если вызванный метод помечен @Transactional. Кроме того, прокси-сервер должен быть полностью инициализирован, чтобы обеспечить ожидаемое поведение, поэтому вам не следует полагаться на эту функцию в коде инициализации (т. Е. @PostConstruct).
в аннотированном классе вашего провайдера с @Component
вызов прокси достигает метода, который не аннотирован с помощью @Transactional
, и выполняет собственный вызов или внутренний вызов метода с аннотацией @Transactional
, который не работает, как объяснено ранее
Для контроллера или службы метод, отмеченный @Transactional
, вызывается первым (внешний вызов), который инициирует транзакцию. Поток кода в контексте этого метода находится в транзакции, и все последующие методы участвуют в этой транзакции, и вы не видите исключение - no Session
.
Надеюсь, это поможет