Spring boot集成mybatisplus多数据源(dynamic)踩坑记录

应为业务需要,所以需要集成多数据源,此处做一个记录。

此处使用了dynamic-datasource-spring-boot-starter的数据源切换

一:引入jar包

        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>dynamic-datasource-spring-boot-starter</artifactId>
            <version>3.3.0</version>
        </dependency>

二:配置配置文件

spring.datasource.dynamic.primary=master
spring.datasource.dynamic.strict=false

spring.datasource.dynamic.datasource.master.url=jdbc:mysql://xxxx.xxxx.xxxx:3306/hdt?useUnicode=true&characterEncoding=utf-8&allowMultiQueries=true&useSSL=false&rewriteBatchedStatement=true
spring.datasource.dynamic.datasource.master.username=root
spring.datasource.dynamic.datasource.master.password= xxxxxx
spring.datasource.dynamic.datasource.master.driver-class-name=com.mysql.cj.jdbc.Driver

spring.datasource.dynamic.datasource.hdt16.url=jdbc:mysql://xxxx.xxxxx.xxxx.xxxx3306/hdt2?useUnicode=true&characterEncoding=utf-8&allowMultiQueries=true&useSSL=false&rewriteBatchedStatement=true
spring.datasource.dynamic.datasource.hdt16.username=root
spring.datasource.dynamic.datasource.hdt16.password=123456
spring.datasource.dynamic.datasource.hdt16.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.dynamic.primary=master 指定master为默认数据源
spring.datasource.dynamic.strict=false
#严格匹配数据源,默认false. true未匹配到指定数据源时抛异常,false使用默认数据源

当pom文件引入而且配置了数据源。指定了默认数据源。

@Service
public class UpdateLog16ServiceImpl {

    @Autowired
    private UpdateLogMapper updateLogMapper;

    @DS("hdt16")
    public boolean save16Log(UpdateLogEntity log) {
        return updateLogMapper.addUpdateLog(log);
    }

}

使用@DS来切换数据源。

切记切记切记

当切换数据源失败的时候:

1:禁止使用事务注解

原因: spring开启事务后会维护一个ConnectionHolder,保证在整个事务下,都是用同一个数据库连接。

请检查整个调用链路涉及的类的方法和类本身还有继承的抽象类上是否有@Transactional注解。

如强烈需要事务保证多个库同时执行成功或者失败,请查看事务专栏的解决办法。

2:方法内部调用

public UserService {

    @DS("first")
    public void test1() {
        // do something
         test2();
    }

    @DS("second")
    public void test2() {
        // do something
    }
}

这样切换是不行的,底层原理是基于aop去实现,内部方法调用是不会使用aop的

解决方法:

把test2()方法提到另外一个service,单独调用。


版权声明:本文为qq_41822960原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。