在服务层的方法上加上 DynamicDataSource 注解来指定服务层方法选择使用哪个数据源
缺点
- 同一个业务层方法中可能即会涉及到 创建(Create)、更新(Update)和删除(Delete)操作,也会涉及到 读取(Read)操作,当涉及到CUD操作时方法需要走主库,同时也会让同方法内的R操作也走了主库
- 业务层中的方法相互调用时目前的主从切换较为复杂,如,一个查询语句可能被服务层A方法调用的时候走了主库,被服务层B方法调用的时候又走了从库,当服务层相互交互存在复杂调用时,这种关系更难梳理清楚,最终导致还是有很多查询操作走了主库,大大的降低了主从分离的效果
- 动态数据源切换应该放到底层Mapper来实现,而不应该放到高层的业务层中实现,放在Mapper中实现是因为Mapper中的方法不会存在相互调用,所有具有原子性和高内聚
- 目前动态数据源注解是加在服务层的方法上的,如果同类中的方法相互调用可能会受到Spring AOP机制的影响导致注解失效
改造后的数据源切换方案
改造后的方案,主要是解决上面老方案中提到的几个缺陷,新方案是把数据源的选择放到了Mapper来实现,根据Mapper层的方法来进行不同数据源的选择
优点
- 同一个服务层方法中如果涉及到了 创建(Create)、更新(Update)和删除(Delete)读取(Read)操作时 R操作会走从库,CUD操作会走主库,不会相互影响
- 不会出现一个R操作,在服务层A方法中走了从库,在服务层B方法中走了主库的情况,R操作默认会自动走从库(除非强制选择走主库)
- 不会存在同类中的方法相互调用可能会受到Spring AOP机制的影响导致注解失效的问题
缺点
- 如果是自定义扩展Mapper的话,查询操作的方法名必须以(select、count、find、get、query、list)开头,相对来说对开发人员的命名规则有相应的要求,灵活性稍微受到影响
- 如果需要强制指定R的操作走主库的话,需要在Mapper的方法上加上@Master注解来实现,但此方式不推荐在原生生成的Mapper中使用,推荐在ext 的扩展Mapper中使用
示例
|