My Spring Boot application doesn't know which database to connect to at the start of the application. It will receive the input in the HTTP request body (that includes dbtype,dbservername etc) at runtime and it should connect to a DB instance based on this input.
For similar questions that I checked on StackOverflow, people have suggested ways to create Datasource instances beforehand and then switch during runtime based on the input. However, I don't want to hardcode configurations for different DBs. I want the application to create the JdbcTemplate, Datasource, and TransactionManager instances at runtime.
Here's what I have tried so far to create the JdbcTemplate and Datasource instance at runtime:
class DBConfig{
private DataSource getMSSQLDatasource(String servername){
// create MSSQL datasource using the servername
}
private DataSource getDB2Datasource(String servername){
// create DB2 datasource using the servername
}
private JdbcTemplate setJdbcTemplate(String dbtype, String servername){
return new JdbcTemplate(dbtype.equals("DB2") ? getDB2Datasource(servername) : getMSSQLDatasource(servername));
}
}
So I can create JdbcTemplate and Datasource at runtime. But I also want to execute some of the queries as a transaction using @Transactional for which I would need a TransactionManager. I am not sure how to configure it dynamically at runtime.
So I have two questions:
- Is there a way to configure TransactionManager dynamically (just like I have done with JdbcTemplate)? If so How?
- Any suggestions?
I tried a workaround and it seems to be working fine so far. Any suggestions would be really helpful.
Created a custom class (DynamicTransactionManager) that implements PlatformTransactionManager:
Now in the DBConfig class, while creating JdbcTemplate, access DynamicTransactionManager's bean and set the DataSource dynamically like this:
So basically DynamicTransactionManager's bean is getting created at the start of the application (because of @Component) but the transaction manager inside it is not initialized.
At runtime, while creating the JdbcTemplate in the DBConfig, I am extracting the bean of class DynamicTransactionManager from applicationContext and injecting the DataSource into this bean using the setDatasource method.