“刚上线的系统突然要对接3个数据库,老板要求不重启服务随时切换!”——这是某金融公司开发团队的真实需求。动态数据源切换,看似简单,实则暗藏玄机:事务失效、连接泄漏、配置冲突……今天这篇实战指南,教你用注解+AOP+多级缓存实现丝滑切换,附赠避坑大全和性能优化技巧!
一、为什么需要动态切换数据源?
动态数据源的核心价值在于灵活应对多数据库场景,例如:
- 读写分离:主库写,从库读,提升并发能力。
- 多租户架构:每个租户独立数据库,数据隔离更彻底。
- 数据迁移:新旧系统并行时,需同时操作多个库。
二、手把手实现动态切换
1. 核心四件套:配置、路由、上下文、切面
(1) 多数据源配置
在application.yml
中定义主库和从库(以MySQL为例):
# 主数据源
spring.datasource.master.url=jdbc:mysql://localhost:3306/master
spring.datasource.master.username=root
spring.datasource.master.password=root
# 从数据源1
spring.datasource.slave1.url=jdbc:mysql://localhost:3306/slave1
spring.datasource.slave1.username=root
spring.datasource.slave1.password=root
(2) 动态路由类
继承AbstractRoutingDataSource
,根据当前线程标记选择数据源:
public class DynamicDataSource extends AbstractRoutingDataSource {
@Override
protected Object determineCurrentLookupKey() {
return DataSourceContextHolder.getDataSourceKey();
}
}
(3) 数据源上下文
使用ThreadLocal
保存当前数据源标识,避免多线程污染:
public class DataSourceContextHolder {
private static final ThreadLocal<String> CONTEXT = new ThreadLocal<><