Springboot 多数据源事务,切换数据源+事务

项目有多个数据源, 根据配置文件配置的连接数来自动生成多数据源配置 并且使用 aop切换数据源,、使用的是 AbstractRoutingDataSource 重写 determineCurrentLookupKey 方法。

在切换数据源之前 @Transactional 先执行 ,此时会去获取数据源,而此时数据源还没有切换 就会获取默认的数据源 。 这种情况会导致数据源切换失败
源码:
在这里插入图片描述
如果不用事务,切换数据源是可以的。

2, 其它方式

@Configuration
@MapperScan(basePackages = "com.modules.**.dao",sqlSessionTemplateRef = "masterSqlSessionTemplate")
public class MasterDataSourceConfig {

    @Bean
    @Primary
    @ConfigurationProperties(prefix = "spring.datasource.master")//设置配置
    public DataSource masterDataSource() {
        return DruidDataSourceBuilder.create().build();
    }

    @Bean
    @Primary
    public SqlSessionFactory masterSqlSessionFactory() throws Exception {
        SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
        bean.setDataSource(masterDataSource());
        bean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath*:mybatis/master/**/*.xml"));
        return bean.getObject();
    }

    @Bean
    @Primary
    public DataSourceTransactionManager masterTransactionManager() {
        return new DataSourceTransactionManager(masterDataSource());
    }

    @Bean(name = "masterSqlSessionTemplate")
    public SqlSessionTemplate sqlSessionTemplate()
            throws Exception {
        return new SqlSessionTemplate(masterSqlSessionFactory());
    }
}

@Configuration
@MapperScan(basePackages = "com.dao",sqlSessionTemplateRef = "twoSqlSessionTemplate")
public class TwoDataSourceConfig {

    @Bean
    @ConfigurationProperties(prefix = "spring.datasource.sqlserver")//设置配置
    public DataSource twoDataSource() {
        return DruidDataSourceBuilder.create().build();
    }

    @Bean
    public SqlSessionFactory twoSqlSessionFactory() throws Exception {
        SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
        bean.setDataSource(twoDataSource());
        bean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath*:mybatis/two/**/*.xml"));
        return bean.getObject();
    }

    @Bean
    public DataSourceTransactionManager twoTransactionManager() {
        return new DataSourceTransactionManager(twoDataSource());
    }


    @Bean(name = "twoSqlSessionTemplate")
    public SqlSessionTemplate sqlSessionTemplate()
            throws Exception {
        return new SqlSessionTemplate(twoSqlSessionFactory());
    }
}
 **非primary的事务管理器 需要在@Transactional中加上事务管理器beanName, 不能事务不会起作用, 默认使用的是primary的事务管理器**
  @Autowired
    private MasterMapper masterMapper;

    @Autowired
    private TwoMapper twoMapper;

    @RequestMapping("/test")
    @Transactional(rollbackFor = Exception.class)
    public void report(){
        twoMapper.saveConfig(info);
        int i = 1 /0;
    }


    // 非primary的事务管理器 需要在@Transactional中加上事务管理器beanName
    @RequestMapping("/test1")
    @Transactional(rollbackFor = Exception.class,value = "twoTransactionManager")
    public void test1(){
        masterMapper.save(info);
        int i = 1 / 0;
    }

注意:此事务内只能保证同一个数据源, 非分布式事务

参考: https://blog.csdn.net/study_zmm/article/details/106790031
http://www.linhao007.com/2017/11/23/01/

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值