Problem Description

I use spring framework in my projects. In my application scenario, I need to use multiple data sources. In order to ensure that each data source transaction can be consistent and isolated from each other, I defined multiple transaction managers. I add the @Transactional annotation to the method that requires transaction processing and specify the specific transaction manager through @Transactional("transactionManager").

The Spring container not only manages the bean lifecycle but also includes the management of the dependencies between the beans. For example, the dependencies between the beans that is woven by the @Autowired and @Resource annotations can be established, which in order to close the application correctly according to the bean dependencies.

However, I find the approach that the @Transactional annotation specifies the 'transactionManager' qualifier does not establish the dependency between the beans, so that an exception may occur when the application is closed and the bean is destroyed. For example, when the transaction manager bean is destroyed first, if other beans that depend on the transaction manager bean have not been destroyed, there will throw exceptions.

Java code below

@Component
@Slf4j
public class UserManager {

    @Resource
    private UserDao userDao;

    @Transactional("transactionManager")
    public UserEntity updateUserInfo(UserReq req) {
        ...
    }

}

Question

I don't understand the design that the @Transactional annotation can't establish the dependencies between the beans. What is the starting point of this design? If it is reasonable and acceptable, then how can we ensure that the dependencies can be established correctly?

Comment From: sbrannen

However, I find the approach that the @Transactional annotation specifies the 'transactionManager' qualifier does not establish the dependency between the beans, so that an exception may occur when the application is closed and the bean is destroyed. For example, when the transaction manager bean is destroyed first, if other beans that depend on the transaction manager bean have not been destroyed, there will throw exceptions.

Can you provide a concrete, working example where such an exception occurs as well as the stack trace?

Comment From: upcgaolei

Yes, I will provide an example project to restore problem scenario.

Comment From: upcgaolei

Hello, this is a concrete, working example demo, https://github.com/upcgaolei/spring-sample.

Comment From: jhoeller

As of 6.2, we leniently tolerate late retrieval of existing instances during destroySingletons(), making late bean interactions possible during destroy method invocations even for retrievals from an on-demand supplier or async worker etc. After all, such late interactions were already possible for bean instances that got stored directly, and late retrieval was possible for beans without destroy methods (even if they were part of a depends-on arrangement in the other direction), so we may also tolerate interactions when retrieved on demand now: typically for validators and transaction managers, late-bound and/or potentially late-qualified.