We have several databases, and then several DataSources in a DataSourceRouter.
That way, we can decide what database to use programmatically. But when it comes to annotations, it's not clear to me how to set the transaction context.
There are a few articles covering how to use different data sources, like: https://www.baeldung.com/spring-abstract-routing-data-source https://medium.com/innomizetech/dynamic-multi-database-application-with-spring-boot-7c61a743e914
But as I said, they set the proper dataSource programmatically, like:
DatabaseContextHolder.set(tenantName);
val response = this.doSomethingInDatabase();
DatabaseContextHolder.clear();
I could use that at a method level, instead of at the class level. So I would have something like @Transactional("TransactionBeanName"). Doing that works, but requires programmatic code, and also I need to split the logic into two public methods.
class SomeService() {
fun entrypoint(tenantName: String) {
val data = getData()
withTenant(tenantName) {
doSomething(tenantName, data)
}
}
private fun withTenant(tenantName: String, action: () -> Unit) {
DatabaseContextHolder.setTenant(tenantName)
action()
DatabaseContextHolder.clearTenant()
}
@Transactional("byteProJpaTransactionManager")
fun doSomething() { ... } // <-- needs to be public to be transactional
...
}
So I'm wondering what would be the best practice here. Any ideas?