当前位置: 代码网 > it编程>编程语言>Java > springboot使用dynamic做多数据源配置全过程

springboot使用dynamic做多数据源配置全过程

2025年12月01日 Java 我要评论
最近项目需求,需要用到多数据源配置,经过一番学习完成需求功能开发,本文介绍一下我用到的dynamic做动态数据源配置。1. 依赖导入这里用到dynamic依赖,和对应的数据源(mysql,oracle

最近项目需求,需要用到多数据源配置,经过一番学习完成需求功能开发,本文介绍一下我用到的dynamic做动态数据源配置。

1. 依赖导入

这里用到dynamic依赖,和对应的数据源(mysql,oracle等)依赖。以下是dynamic依赖:

	<dependency>
		<groupid>com.baomidou</groupid>
		<artifactid>dynamic-datasource-spring-boot-starter</artifactid>
		<version>3.5.0</version>
	</dependency>

2.yml配置

yml配置主要是将多个数据源分别配置,并指定默认数据源,具体yml配置参考如下:

spring:
  datasource:
    dynamic:
      primary: kingbase # 设置主库为kingbase
      strict: false # 严格匹配数据源,默认false,当为true时,未匹配到指定数据源时抛异常,false未匹配到指定数据源会使用默认数据源
      datasource:
        kingbase: # 这的kingbase是自定义的数据源名称,不是指数据库的类型
          url: jdbc:kingbase8://${database_host:127.0.0.1}:${database_port:54323}/${database_dbname:kingbase}?servertimezone=gtm%2b8
          username: ${database_username:system}
          password: ${database_password:12345}
          driverclassname: com.kingbase8.driver
          type: com.alibaba.druid.pool.druiddatasource
        mysql:
          url: jdbc:mysql://${database_host:127.0.0.1}:${database_port:3306}/${database_dbname:mysql}?servertimezone=gmt%2b8&useunicode=true&characterencoding=utf8&usessl=false
          username: ${database_username:root}
          password: ${database_password:1234}
          driverclassname: com.mysql.cj.jdbc.driver
          type: com.alibaba.druid.pool.druiddatasource

使用时,只需要在对应的mapper上,使用注解@ds(“mysql”),指定当前mapper数据源为mysql数据源

3.多数据源失效问题

常见的多数据源失效问题可以从配置方面去排查,例如,yml配置,ds指定数据源配置等方面。

这里我介绍一下我在使用过程中遇到的多数据源失效问题。

问题情境

我在同一个方法中,先调用了主数据源(kingbase)中的某个表数据,然后再调用了从数据源(mysql)中的数据,然后执行下面业务逻辑,我这后面涉及到对数据库的写操作,我在方法上用了@transactional注解管理事务,然后我发现,调用主数据源的时候,数据获取正常,调用从数据源的时候,报错没有xx表,查看报错信息为kingbasesqlexception,就知道了调用的主数据源数据,多数据源失效了。于是开始排查

问题排查

(1) 配置问题

首先查看是否是配置原因,检查yml配置和mapper配置是否正确,然后我写了个测试接口,测试多数据源是否有效,测试接口直接调用获取从数据源数据,获取正确,不是这个原因。

(2)方法代理问题

我将获取数据的代码单独封装方法,然后通过自动注入service,用注入的service调用方法获取对应所需的数据,仍然发现此问题,不是这个原因。

(3)事务管理问题

这里我查询了相关资料,得知在方法上添加事务,事务只会对一个数据源进行事务管理。其实说得通俗易懂一点就是,一个数据库的事务管不住另一个数据库的事务。

ok,问题找到现在开始解决问题。

问题解决

根据我这问题产生原因,思路很简单,对每个数据源数据获取单独使用事务管理,这里可以了解一下spring的事务传播机制,默认传播机制为propagation.required(如果当前没有事务,就新建一个事务,如果已

经存在一个事务中,加入到这个事务中),所以在我前面使用方法代理排查问题的时候,还是不行,因为使用的默认传播机制。

这里补充一下事务传播机制:

propagation_required如果当前没有事务,就新建一个事务,如果已经存在一个事务中,加入到这个事务中。这是最常见的选择。- 默认
propagation_supports支持当前事务,如果当前没有事务,就以非事务方式执行。
propagation_mandatory使用当前的事务,如果当前没有事务,就抛出异常。
propagation_requires_new新建事务,如果当前存在事务,把当前事务挂起。
propagation_not_supported以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。
propagation_never以非事务方式执行,如果当前存在事务,则抛出异常。
propagation_nested如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则执行与propagation_required类似的操作

基于上面提到的事务传播机制,我这将对数据库的操作封装成独立方法,然后我使用propagation_requires_new传播机制,新建事务,使用方式@transactional(propagation = propagation.requires_new)。然后再次测试功能,发现报另一个错了,这就说明这个多数据源失效问题,已经解决。我这的另一个错产生原因主要是项目中使用到了neo4j,而这个事务只支持默认事务,所以报错。

问题解决其他思路

我这因为neo4j不适合使用多个事务进行事务管理。所以我这将代码逻辑进行了处理,我将接口的入口方法,单独封装方法,然后将数据进行业务逻辑处理后,统一添加到数据库和neo4j中,这里我将数据添加逻辑单独封装方法进行处理,最后问题解决,功能测试通过。

其实也可以在代码中不使用@transcational注解,可以在代码块中手动开启提交回滚事务,也可以达到效果。

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持代码网。

(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2025  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com