Using it as prototype is a not a good practice. This actually means that each time transactionManager()
is called, a new TransactionManager
is created, which is redundant resource consuming, as a single instance for each TransactionManager
configuration is enough.
Instead, create some factory bean, you can call it TransactionManagerFactory
, which exposes a getter such as PlatformTransactionManager getUserTxManager(SomeRelevantUserDetails)
. This factory will create the various PlatformTransactionManager
s for the various DB vendors only once each and return it to the caller according to SomeRelevantUserDetails
.
TransactionManagerFactory class:
@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;
}
}
Other service that requires a user-dependent transaction manager:
@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
}
}