项目场景:
基于Thingsboard二次开发,将项目中数据库替换为mysql,基础数据放置于一个mysql库,时序数据放置于另一个mysql库,涉及到项目多数据源配置,使用了dynamic-datasource-spring-boot-starter进行多数据源配置,通过注解的方式配置不同模块使用不同数据源
问题描述:
由于thingsboard本身通过@SqlTsLatestAnyDao类似这些注解标注了哪些Dao操作是写时序数据,所以我在SqlTsLatestAnyDao内加上了动态数据源切换的注解,如图:
但是实际上是在有些场景并没有切换到ts对应的数据源上
原因分析:
通过阅读dynamic-datasource-spring-boot-starter源码,以及断点调试,发现@DS(“ts”)注解是可以被AOP切面拦截到的,加了注解可以进入到对应的查找注解标示,将ts放入到当前线程ThreadLocal中,但是在这段查找注解的代码中经过一连串不同维度的查询最终都没有找到@DS注解,也就是说我加了@DS注解进入了切面,但是最终查找@DS注解又没有找到,没有找到最后会将一个空字符串放入ThreadLocal,最终选择数据源的时候,发现空字符串实际就会使用主数据源了,找不到的源码可能是因为注解标注在了Repository上,里面实现逻辑是动态代理生成的代理类
解决方案:
起初怀疑这个是不是dynamic-datasource-spring-boot-starter的BUG,因为这个地方如果找不到@DS注解就不要往缓存和ThreadLocal中放置空字符串的话,可以在一定程度上避免这个问题,在考虑要不要改改代码向baomidou提交Issues问问这个问题,但是最后发现baomidou官方其实是强烈不建议将动态数据源的注解标注在Dao或者Repository上的,所以最终我将@DS拿出来单独放在对应的Service上或者方法上,问题解决。最后建议不要在使用dynamic-datasource-spring-boot-starter的时候在一些奇怪的地方标注数据源
评论区