| 动态数据源是这样实现的: --------------------------
 动态数据源类集成了Spring提供的AbstractRoutingDataSource类,AbstractRoutingDataSource 中获取数据源的方法就是 determineTargetDataSource,而此方法又通过 determineCurrentLookupKey 方法获取查询数据源的key。
 
 所以如果我们需要动态切换数据源,就可以通过以下两种方式定制:
 
 1. 覆写 determineCurrentLookupKey 方法
 
 通过覆写 determineCurrentLookupKey 方法,从一个自定义的 DynamicDataSourceContextHolder.getDataSourceKey() 获取数据源key值,这样在我们想动态切换数据源的时候,只要通过  DynamicDataSourceContextHolder.setDataSourceKey(key)  的方式就可以动态改变数据源了。这种方式要求在获取数据源之前,要先初始化各个数据源到 DynamicDataSource 中,我们案例就是采用这种方式实现的,所以在 MybatisConfig 中把master和slave数据源都事先初始化到DynamicDataSource 中。
 --------------------------
 
 通过线程Local设置数据源Key即可。
 
 
 现象:
 有几个数据源,添加数据时,挨个切换,然后insert数据。
 发现有一个数据源,总是插入不进去,莫名其妙。
 debug跟了一下,发现也没报错,见鬼了。
 
 后来,单步debug进去,发现conn貌似不正确,莫名其妙。
 
 后来,发现貌似走了事务,sqlSession是从线程Local获取的,类似于缓存
 
 查看spring配置文件,确实给insert开头的配置了事务。
 
 关键是:
 DynamicDataSourceContextHolder.setDataSourceKey(key)
 这东西写在了insertXX()方法里边,
 既然开了事务,肯定是调用方法之前就开始了事务,肯定就获取了连接,
 方法里面再切数据源,对自己肯定没毛用了,相当于给后一个loop切了数据源。
 
 也就是:第二次循环的数据源,实际是第一次方法里面切换的。
 第三次循环的数据源,实际是第二次方法里面切换的。
 最后一次循环的数据源,是倒数第二个切换的。
 
 结果就是:最后一个数据源,实际没有执行insert。
 
 解决办法:
 在调用xxService.insertXXX();之前切换数据源,问题解决。
 
 
 |