MyBatis-Plus多数据源配置与事务与批量注意点

一、在使用mybatisplus时(以下简称mp)会有配置多数据源的情况,配置方式比较简单:

1、首先配置依赖

        
            com.baomidou
            mybatis-plus-boot-starter
            3.5.1
        
        
            com.baomidou
            dynamic-datasource-spring-boot-starter
            3.5.0
        

2、配置文件中配置多组数据源:配置多个datasource并指定primary主库

spring:
  datasource:
    dynamic:
      p6spy: true
      strict: false
      primary: aaa
      datasource:
        '[aaa]':
          hikari:
            max-pool-size: 15
          url: jdbc:xxx
          username: xxx
          password: xxx
          driver-class-name: com.mysql.cj.jdbc.Driver
        '[bbb]':
          hikari:
            max-pool-size: 15
          url: jdbc:xxx
          username: xxx
          password: xxx
          driver-class-name: com.mysql.cj.jdbc.Driver

3、在需要切换数据库的位置使用@DS("bbb")注解,不指定默认主库。此注解一般使用在mapper或者service上,根据需要指定。

4、到这里基本就是多数据源的配置与使用。以下是使用中可能遇到的一些问题

二、一般使用都是在需要切换数据库在使用中发现经常出现几个小问题,

1、发现配置多数据源之后批量执行的方法都走的主库。

2、针对相同库的事务如何处理。

3、针对不同库的事务如何处理。

在使用多数据源的时候可以开启debug日志查看在每次创建SqlSession之后选用的是哪个数据源。例如:

 1、针对问题1,在使用mp的时候可能执行一些批量的方法,比如saveBatch等,进入saveBatch方法中可以看到在这个方法上默认有@Transactional注解,对于该注解默认使用的都是主库,所以对于从库的一些操作因为无法切换从库产生一些问题。解决方法:

  • 针对问题1的同一个源的批量操作,可以在外部方法使用@DS("bbb")优先指定需要操作的源。
  • 针对问题1的不同源的批量操作,可以考虑自己实现批量操作等。

 2、针对问题2,针对相同库的事务,可以使用@DS与@Transactional搭配实现

 3、针对问题3,这对不同库的事务,可以使用@DSTransactional实现

总结一些:对于mp的多数据源的事务或者查询问题首先看每次sql执行时选择的源,另外使用@DS与@Transactional与@DSTransactional三个注解基本可以解决遇到的事务失效等问题。针对三个注解给一个描述语:

@DS:就是用来切换数据源

@Transactional:默认只针对主库

@DSTransactional:可以理解为在事务中可以切换数据源

三、针对@Transactional与@DSTransactional做一个简单的解释。

  1. @Transactional是spring的注解目的就是开启事务,所以在该注解被扫描到的时候就去获取DataSource,此时DynamicDataSourceContextHolder队列中无任务元素,所以获取到的dsKey就是null,之后通过DynamicRoutingDataSource方法中的determinePrimaryDataSource获取主库的DataSource。
  2. @DSTransactional是mp中的注解,该注解下的所有@DS注解在invoke方法中向DynamicDataSourceContextHolder中压入元素,之后在获取determineDataSource的时候或获取到一个dsKey从而选择正确的DataSource。

希望以上可以帮到一些小伙伴,如果错误的点大家可以多多留言哈~

你可能感兴趣的:(mybatis,mysql)