springboot源码分析 - AbstractRoutingDataSource多数据源方案的分析

    原本想用springboot+mybatis做多数据源的切换方案,想通过借鉴网上现有的方案,结果搜索后大量都是使用AbstractRoutingDataSource多数据源方案,通过实践后,发现如果声明了事务,将会在事务内部切换数据源失败。结果,就是debug,看源码找原因。下面是springboot+mybatis的调用栈,如果有点功力的同学们一看就知道了。

存在transaction情况下

@Transactional切面切入拦截
DataSourceTransactionManager
    doBegin
		从threadlocal holder中获取connection
			获取不到
				获取连接
					AbstractRoutingDataSource#getConnection
				封装holder,存入threadLocal中,key为AbstractRoutingDataSource			
			获取到,不再AbstractRoutingDataSource#getConnection

此时,已经获取到connection,如果@Transactional注解还有切换数据源的切面,则使用切面中切换好的数据源,如果没有其他注解,则获得配置的defaultDataSource的数据源。

======================= step2 ===============================
之后,调用mybatis的mapper

mybatis
  Executor
    prepareStatement
      getConnection()
        SpringManagedTransaction
		  getConnection() 
			 查看threadLocal中,key为AbstractRoutingDataSource,取出connection的holder
				如果有用holder里面的connection
				如果没有从AbstractRoutingDataSource获取新的连接


=======================  step3  ====================================
@Transactional注解的方法中还在调用其他需要切换数据源的service或者方法

仍然走step2,由于从threadLocal可以获取到connection,所以不会从AbstractRoutingDataSource获取新的连接,也就是切换数据源失败

    这里的AbstractRoutingDataSource#getConnection方法是切换数据源的关键。如果在事务过程中,我们mybatis每次都是获取threadlocal中key为AbstractRoutingDataSource的connection,则不会再调用AbstractRoutingDataSource中的getConnection方法切换数据源。

    如果想解决这个问题,自定义吧。。。

 

转载于:https://my.oschina.net/thinwonton/blog/2962391

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值