将事务管理器bean作为Prototype作用域是一种好的做法

时间:2014-01-03 03:23:13

标签: spring multiple-databases transactionmanager

我想基于用户登录连接不同的数据库,所以我将TransactionManager bean作为Prototype范围,并且每次创建transacionManager bean,并且运行良好。但是,当应用程序的范围增加以及它的稳定性时,它是否良好?

有什么想法吗?感谢。

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

1 个答案:

答案 0 :(得分:0)

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

相反,创建一些工厂bean,你可以称之为TransactionManagerFactory,它会公开一个getter,例如PlatformTransactionManager getUserTxManager(SomeRelevantUserDetails)。该工厂将仅为各个数据库供应商创建各种PlatformTransactionManager,并根据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
    }
}