Spring 将事务管理器bean作为原型作用域是一种好的实践吗

Spring 将事务管理器bean作为原型作用域是一种好的实践吗,spring,multiple-databases,transactionmanager,Spring,Multiple Databases,Transactionmanager,我希望基于用户登录连接不同的数据库,因此我将TransactionManager bean作为原型范围,它每次都在创建transacionManager bean,并且运行良好。但是,当应用程序的范围增加时,它是否良好?它的稳定性如何 有什么想法吗?谢谢 @Bean(initMethod = "init", destroyMethod = "destroy") @Scope(value = "prototype") public PlatformTransactionManager transa

我希望基于用户登录连接不同的数据库,因此我将TransactionManager bean作为原型范围,它每次都在创建transacionManager bean,并且运行良好。但是,当应用程序的范围增加时,它是否良好?它的稳定性如何

有什么想法吗?谢谢

@Bean(initMethod = "init", destroyMethod = "destroy")
@Scope(value = "prototype")
public PlatformTransactionManager transactionManager() {

使用它作为原型不是一个好的实践。这实际上意味着每次调用
transactionManager()
时,都会创建一个新的
transactionManager
,这会消耗冗余资源,因为每个
transactionManager
配置的单个实例就足够了

相反,创建一些工厂bean,您可以称之为
TransactionManagerFactory
,它公开了一个getter,比如
PlatformTransactionManager getUserTxManager(一些相关的用户详细信息)
。此工厂将为各种DB供应商创建各种
PlatformTransactionManager
s,每个只创建一次,并根据
SomeRelevantUserDetails
将其返回给调用者

TransactionManagerFactory类:

@Component
public class TransactionManagerFactory {

    private final PlatformTransactionManager mySqlTxManager;
    private final PlatformTransactionManager db2TxManager;
    private final PlatformTransactionManager hsqlTxManager;

    @Autowired
    protected TransactionManagerFactory(
        @Qualifier("mySqlTxManager") PlatformTransactionManager mySqlTxManager
        @Qualifier("db2TxManager") PlatformTransactionManager db2TxManager
        @Qualifier("hsqlTxManager") PlatformTransactionManager hsqlTxManager) {

        this.mySqlTxManager = mySqlTxManager;
        this.db2TxManager = db2TxManager;
        this.hsqlTxManager = hsqlTxManager;
    }

    public PlatformTransactionManager getUserTxManager(SomeRelevantUserDetails userDetails) {
        PlatformTransactionManager userTxManager = // put here logic to determine
        return userTxManager;
    }
}
需要依赖于用户的事务管理器的其他服务:

@Component
public class UsesTxManagerFactory {

    private final TransactionManagerFactory txManagerFactory;

    @Autowired
    protected UsesTxManagerFactory(TransactionManagerFactory txManagerFactory) {
        this.txManagerFactory = txManagerFactory;
    }

    public void someMethod() {
        SomeRelevantUserDetails userDetails = // create the relevant details
        PlatformTransactionManager txManager = getUserTxManager(userDetails);
        // perform transaction
    }
}

非常感谢您的回复。我将以这种方式尝试并让您知道。但在我的例子中,我不知道需要创建多少个事务管理器,它是动态的,取决于访问应用程序的用户。使用prototype时,即使是具有相同必需事务管理器属性的同一用户,也会导致每次创建一个新的
PlatformTransactionManager transactionManager()调用了
。如果“动态”是指客户可以通过一些启动前配置对其进行配置,则TransactionManagerFactory应在初始化期间加载该配置并创建所有配置。如果“动态”指的是完全动态的-即使在初始化之后,用户也可以请求一个新的tx管理器-那么您可以使用
prototype
bean来创建新的tx管理器,只有它应该被
TransactionManagerFactory
包装,这应该通过相关知识获得,以确定何时应该创建新的管理器以及何时可以将现有的管理器返回给客户端。我正在寻找一个解决方案,我们将有一个应用程序的单个实例并连接到多个数据库,每个客户一个数据库,一个客户可能有多个用户。因此,在我的应用程序中,我需要为每个客户创建一个事务管理器,这样属于该客户的所有用户都将使用同一个事务管理器,如果另一个客户的用户登录,则需要创建一个具有各自数据源详细信息的新事务管理器。客户数据库信息将存储在主数据库中,因此每次用户登录时都会再次验证主数据库。因此,如果有人遇到这种解决方案,这将非常有帮助。我看了几天,有一个解决方案只用于切换数据库,但我需要同时连接到多个数据库。