多数据源切换(二)

多数据源切换(二)

业务背景

​ 在上一节中的思考题中:在externalServiceImpl#insert方法上加上@Transactional 事务注解,则无法切换数据源,只会使用主数据源。

​ 本文主要探究并解决@DS加上@Transactional 注解失效的问题

探究

​ 在上一节中,通过实现AbstractRoutingDataSource接口完成了当前线程多数据源的动态切换,其中通过查看源码可以看到AbstractRoutingDataSource实现切换数据源的主要方法为determineTargetDataSource(),其中有对于当前使用数据源的判断:
​ 当datasource为null,lenientFallback为true且lookupkey为null,切换指定数据源
​ 当datasource不为null时,默认使用当前数据源
在这里插入图片描述

​ 那么通过debug ==AbstractRoutingDataSource#determineTargetDataSource()==方法、@DS注解切面、@Transactional切面等类,我们很容易就分析出以下结论:在这里插入图片描述

  1. 在一开始进入controller层时未指定要使用数据源,所以在执行使用的是默认数据源master_db。
  2. 在==masterUserService.insert(masterUser)==执行时使用的master_db数据源,插入成功。
  3. 在==externalUserService.insert(externalUser)==时:@Transactional注解切面作用的优先级在自定义注解@DS切面之前,因此执行事务切面早执行于自定义切面,而在事务切面需要指定事务所属的数据库,所以就将当前master_db数据设置到了当前线程的上下文当中。
  4. 当执行到@DS的切面中时: ==AbstractRoutingDataSource#determineTargetDataSource()==方法中的datasource使用的是master_db数据源;datasource不为空,因此使用当前的数据源master_db。而不是external_db。

​ 结论: @Transactional注解切面作用的优先级在自定义@DS切面之前,导致当前线程的上文中使用了之前使用的数据源master_db。==AbstractRoutingDataSource#determineTargetDataSource()==根据datasource存在,判断不会切换到extemal_db数据源,因此@DS注解切面中使用的仍然是当前线程上下文的数据源master_db,导致@DS注解失效。

解决思路

​ 既然@DS注解切面优先级低于@Transactional切面,导致@DS切面生效较晚,那么只需要将@DS切面的生效优先级提升到比@Transactional注解生效更高就可以解决当前问题了。

解决方案

在这里插入图片描述

调取localhost:8080//insert/union 接口

在这里插入图片描述

查看数据库结果

在这里插入图片描述

思考题?

​ 假如我们将事务注解加在Controller的方法上,又会出现无法切换数据源,只会使用主数据源,如下图所示:
在这里插入图片描述

探究原因及解决方案在:
多数据源切换(三)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值