Please go through the reference documentation
The following images shows a Conceptual view of calling a method on a
transactional proxy:

Now with this information , a method annotated with @Transactional
will start a transaction only when the call to the method comes in through the proxy object of the class that has this annotated method. This call is mentioned as the external call by the experts in your previous question.
In case of your example ,
The implementation of abstract method AbstractUserDetailsAuthenticationProvider.retrieveUser() is called from AbstractUserDetailsAuthenticationProvider.authenticate() , which is a self invocation. This is what the experts mentions as internal call . Also note that the method authenticate()
is not @Transactional
Go through the documentation under the section Using Transactional
In proxy mode (which is the default), only external method calls
coming in through the proxy are intercepted. This means that
self-invocation (in effect, a method within the target object calling
another method of the target object) does not lead to an actual
transaction at runtime even if the invoked method is marked with
@Transactional. Also, the proxy must be fully initialized to provide
the expected behavior, so you should not rely on this feature in your
initialization code (that is, @PostConstruct).
In your provider class which is annotated with @Component
the call to the proxy reaches a method which is not annotated with @Transactional
and does a self-invocation or internal call to the method annotated with @Transactional
, which does not work as explained earlier
With the Controller or Service , the method annotated with @Transactional
is getting called first (external call) , which initiates a transaction . The code flow within the context of that method is in a transaction and all the subsequent methods are participating in that transaction and you do not see the - no Session
exception.
Hope this helps