SpringBoot多数据源的事务管理

Spring Boot本身并不管理事务,只是提供了 PlatformTransactionManager 接口来供持久层实现来达到事务的管理,Spring Boot 默认使用JDBC来控制事务。

在单数据源的情况下我们无需自己管理事务,Spring Boot 默认使用 DataSourceTransactionManager 来管理事务,我们所做的只要在程序的service层加上 @Transactional 注解即可使用。如下:

@Override
@Transactional(rollbackFor = Exception.class)
public R del(int id) {
    boolean b = dayMapper.updateDelStatus(id);
        // 模拟异常
    int a = 11 / 0;
    return b ? R.ok() : R.error("error");
}

在单数据源的情况下,以上代码可以正常运行处理事务;

但是在多数据源的情况下,以上代码会报错:

No qualifying bean of type 'org.springframework.transaction.PlatformTransactionManager' available: expected single matching bean but found 2:

这个问题产生的原因在于项目中配置了多个数据源,而代码中启用了事务@Transactional注解,导致事务不知道应该用哪个数据源,需要指定数据源才可以重新启用事务。

解决方法:

我们要为每个数据源创建并指定要使用的事务管理器。也即是在spring boot 的数据源配置类中如下:

@Bean(name = "entityTx")
public DataSourceTransactionManager transactionManager(@Qualifier("entityDataSource") DataSource dataSource) {
  return new DataSourceTransactionManager(dataSource);
}

这里是使用jdbc的事务管理器,将名称为entityDataSource 的数据源通过方法参数通过构造器交给jdbc事务管理器管理。 这里只是一个数据源的示例,分别在另外的数据源中做相同配置,只是注意@Bean 注解的name 值不能一样,方法参数注入的数据源作区别即可。

之后在service层加上 @Transactional的 transactionManager属性或者value属性 指定为对应的事务管理器名称即可,也即是@Bean的naem的值,在@Transactional 注解中 transactionManager 属性和value 属性互为别名。

@Override
@Transactional(rollbackFor = Exception.class, transactionManager = "entityTx")
public R del(int id) {
    boolean b = dayMapper.updateDelStatus(id);
        // 模拟异常
    int a = 11 / 0;
    return b ? R.ok() : R.error("error");
}

参考:

https://api.juejin.cn/recommend_api/v1/article/recommend_article_detail_feed
https://blog.csdn.net/qq_46657663/article/details/119790041

本文链接: https://jianz.xyz/index.php/archives/310/

1 + 1 =
快来做第一个评论的人吧~