SpringBoot配置多数据源二

背景

前面我配置了同应用多数据源的。但是在实际开发中,我们需要使用事务,保障业务与数据的可用性。那当配置了多数据源时,默认的事务管理器实际时失效了,它找不到具体需要管理的DataSource。

思考

看源码,@Transactional注解默认使用了一个PlatformTransactionManager 继续将PlatformTransactionManager点进去:

这是spring事务管理的核心接口,使用aop拦截它的实现。它有两个默认的实现org.springframework.transaction.jta.JtaTransactionManager 和org.springframework.jdbc.datasource.DataSourceTransactionManager 。

从之前的配置知道,我并没有使用jta,所以继续往下走,看DataSourceTransactionManager 的实现。

implementation for a single JDBC {@link javax.sql.DataSource}. This class is capable of working in any environment with any JDBC driver, as long as the setup uses a {@code javax.sql.DataSource} as its {@code Connection} factory mechanism.Binds a JDBC Connection from the specified DataSource to the current thread, potentially allowing for one thread-bound Connection per DataSource.

从DataSourceTransactionManager 源码的第一段落就可以发现,它只需要绑定一个DataSource就行了。

由此,我只需要按照springboot的关键词搜索,那么我就能找到一个事务的默认配置。然后被我找到了DataSourceTransactionManagerAutoConfiguration

到这里就很简单了,按照springboot的机制,exclude掉这个类,然后配置一个类似的。我有两个不同的DataSouce, 只需要将这两个DataSource配置给每个不同的事务管理器,然后再使用事务的时候声明使用哪个事务管理器就可以。

ChainedTransactionManager 可以用来管理多个事务管理器。

使用

@Configuration
public class DataSourceTransactionConfig {


    @Bean(name="tm1")
    DataSourceTransactionManager tm1(@Qualifier ("ds1") DataSource datasource) {
        return new DataSourceTransactionManager(datasource);
    }

    @Bean(name="tm2")
    DataSourceTransactionManager tm2(@Qualifier ("ds2") DataSource datasource) {
        return new DataSourceTransactionManager(datasource);
    }

    @Transactional
    @Bean(name = "chainedTransactionManager")
    public ChainedTransactionManager transactionManager(@Qualifier("tm1") PlatformTransactionManager tm1,
                                                        @Qualifier("tm2") PlatformTransactionManager tm2) {
        return new ChainedTransactionManager(tm1, tm2);
    }
}

测试一下,通过。