Using TransactionManager with the @Transactional annotation

832 views Asked by At

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?

0

There are 0 answers