一、多数据源业务场景(管理后台核心场景)
先明确落地场景,避免盲目选型:
-
业务分库:用户库、订单库、日志库、配置库独立拆分
-
读写分离:主库写、从库读,提升后台查询吞吐量
-
多租户隔离:SaaS后台,不同租户独立数据库
-
外部数据对接:后台对接第三方业务库、历史迁移库
-
数据同步/归档:生产库查询、归档库写入备份数据
二、目前主流4种多数据源实现方案(2026最新选型)
按 从简单到复杂、从静态到动态、从原生到框架 排序,覆盖所有企业落地方式:
-
方式一:分包多数据源(多SqlSessionFactory 静态固定)
-
方式二:Spring 原生 AbstractRoutingDataSource 动态路由
-
方式三:MyBatis-Plus Dynamic-Datasource 注解动态切换(企业首选)
-
方式四:中间件代理(Sharding-JDBC/MyCat 分布式层方案)
三、四种方案原理、优缺点、适用场景+完整代码
3.1 方式一:分包多数据源(静态多SqlSessionFactory)
3.1.1 实现原理
通过 @MapperScan 区分不同 Mapper 包路径,分别创建独立的 DataSource、SqlSessionFactory、TransactionManager,不同包下的 Mapper 绑定不同数据源,编译期固定数据源,运行时不可切换。
3.1.2 优缺点分析
✅ 优点:
-
原生 Spring 实现,无第三方框架依赖,零侵入
-
配置简单、结构清晰、新手友好
-
单库事务完全可控,无切换异常
❌ 缺点:
-
运行时无法动态切换数据源,灵活性极差
-
新增数据源需新增配置类、分包,维护成本高
-
不支持跨库动态调用,仅适合固定分库场景
3.1.3 适用场景
数据源固定不变、无需动态切换、简单分库的轻量化后台项目。
3.1.4 核心实战代码
1、yml 多数据源配置
spring:
datasource:
# 主库
master:
url: jdbc:mysql://127.0.0.1:3306/db_master?useSSL=false&serverTimezone=Asia/Shanghai
username: root
password: 123456
driver-class-name: com.mysql.cj.jdbc.Driver
# 从库/日志库
slave:
url: jdbc:mysql://127.0.0.1:3306/db_slave?useSSL=false&serverTimezone=Asia/Shanghai
username: root
password: 123456
driver-class-name: com.mysql.cj.jdbc.Driver
2、主库配置类
@Configuration
@MapperScan(basePackages = "com.admin.mapper.master", sqlSessionFactoryRef = "masterSqlSessionFactory")
public class MasterDataSourceConfig {
@Bean("masterDataSource")
@Primary
@ConfigurationProperties(prefix = "spring.datasource.master")
public DataSource masterDataSource() {
return new DruidDataSource();
}
@Bean("masterSqlSessionFactory")
@Primary
public SqlSessionFactory masterSqlSessionFactory(@Qualifier("masterDataSource") DataSource dataSource) throws Exception {
MyBatisSqlSessionFactoryBean factoryBean = new MyBatisSqlSessionFactoryBean();
factoryBean.setDataSource(dataSource);
return factoryBean.getObject();
}
@Bean("masterTransactionManager")
@Primary
public PlatformTransactionManager masterTransactionManager(@Qualifier("masterDataSource") DataSource dataSource) {
return new DataSourceTransactionManager(dataSource);
}
}
3、从库配置类(结构一致,分包区分)
@Configuration
@MapperScan(basePackages = "com.admin.mapper.slave", sqlSessionFactoryRef = "slaveSqlSessionFactory")
public class SlaveDataSourceConfig {
@Bean("slaveDataSource")
@ConfigurationProperties(prefix = "spring.datasource.slave")
public DataSource slaveDataSource() {
return new DruidDataSource();
}
@Bean("slaveSqlSessionFactory")
public SqlSessionFactory slaveSqlSessionFactory(@Qualifier("slaveDataSource") DataSource dataSource) throws Exception {
MyBatisSqlSessionFactoryBean factoryBean = new MyBatisSqlSessionFactoryBean();
factoryBean.setDataSource(dataSource);
return factoryBean.getObject();
}
@Bean("slaveTransactionManager")
public PlatformTransactionManager slaveTransactionManager(@Qualifier("slaveDataSource") DataSource dataSource) {
return new DataSourceTransactionManager(dataSource);
}
}
3.2 方式二:原生 AbstractRoutingDataSource 动态路由
3.2.1 实现原理
Spring 提供的原生动态数据源抽象类,通过 ThreadLocal 存储当前数据源标识,重写路由方法,运行时根据标识动态切换数据源,底层为单 SqlSessionFactory 多数据源路由。
3.2.2 优缺点分析
✅优点:
-
原生无依赖,轻量化动态切换
-
支持运行时动态切换,无需分包
-
适合简单读写分离、少量动态数据源场景
❌ 缺点:
-
需要手动写 AOP、手动管理数据源标识、清除上下文
-
原生不支持事务切换:开启事务后数据源锁定,无法动态切换
-
动态新增数据源繁琐,需手动注册 Bean
-
多数据源事务完全无法原生支持
3.2.3 适用场景
简单读写分离、无跨库事务、少量动态数据源的中小型后台项目。
3.2.4 核心精简代码
// 1.数据源上下文工具类
public class DataSourceContextHolder {
private static final ThreadLocal<String> DATA_SOURCE_KEY = new ThreadLocal<>();
public static void setDataSource(String key) { DATA_SOURCE_KEY.set(key); }
public static String getDataSource() { return DATA_SOURCE_KEY.get(); }
public static void clear() { DATA_SOURCE_KEY.remove(); }
}
// 2.自定义动态数据源路由
public class DynamicRoutingDataSource extends AbstractRoutingDataSource {
@Override
protected Object determineCurrentLookupKey() {
return DataSourceContextHolder.getDataSource();
}
}
// 3.数据源注册配置
@Configuration
public class DynamicDataSourceConfig {
@Bean
public DynamicRoutingDataSource dynamicDataSource() {
Map<Object, Object> dataSourceMap = new HashMap<>();
// 注册主从数据源
dataSourceMap.put("master", masterDataSource());
dataSourceMap.put("slave", slaveDataSource());
DynamicRoutingDataSource routingDataSource = new DynamicRoutingDataSource();
routingDataSource.setTargetDataSources(dataSourceMap);
routingDataSource.setDefaultTargetDataSource(masterDataSource());
return routingDataSource;
}
}
3.3 方式三:MyBatis-Plus Dynamic-Datasource 动态数据源(企业首选)
3.3.1 实现原理
基于 Spring AbstractRoutingDataSource 封装增强,注解驱动 + AOP 自动切换 ,自动管理 ThreadLocal 上下文、自动清除、支持事务内合理切换、动态刷新数据源配置,是目前后台项目使用率最高的方案。
3.3.2 优缺点分析
✅ 优点:
-
极致简洁:一行注解
@DS("数据源名")完成切换 -
自动上下文管理,无内存泄漏风险
-
支持配置中心动态刷新、热更新数据源
-
兼容 MyBatis-Plus 全功能,适配读写分离、多租户
-
提供专属事务方案,解决大部分跨库事务问题
❌ 缺点:
-
依赖第三方开源组件,需匹配版本适配 SpringBoot3
-
强一致性分布式事务仍需 Seata 辅助
3.3.3 适用场景
90% 企业后台、SaaS多租户、读写分离、多动态数据源、需要事务支持的核心业务。
3.3.4 完整可上线代码(SpringBoot3 适配)
1、引入最新依赖
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>dynamic-datasource-spring-boot-starter</artifactId>
<version>4.3.0</version>
</dependency>
2、yml 多数据源配置
spring:
datasource:
dynamic:
primary: master # 默认主库
strict: false
datasource:
master:
url: jdbc:mysql://127.0.0.1:3306/db_master?useSSL=false&serverTimezone=Asia/Shanghai
username: root
password: 123456
driver-class-name: com.mysql.cj.jdbc.Driver
slave:
url: jdbc:mysql://127.0.0.1:3306/db_slave?useSSL=false&serverTimezone=Asia/Shanghai
username: root
password: 123456
driver-class-name: com.mysql.cj.jdbc.Driver
3、业务层注解切换(核心用法)
@Service
public class UserService {
// 默认主库
public List<User> getMasterUser() {
return userMapper.selectList(null);
}
// 手动切换从库
@DS("slave")
public List<User> getSlaveUser() {
return userMapper.selectList(null);
}
}
3.4 方式四:中间件代理方案(Sharding-JDBC/MyCat)
3.4.1 实现原理
通过中间件统一代理数据库层,业务层零感知多数据源,由中间件自动完成分库分表、读写分离、数据源路由、分布式事务管控。
3.4.2 优缺点分析
✅ 优点:
-
业务代码无侵入,无需手动切换数据源
-
支持分库分表、海量数据分片、自动读写分离
-
原生支持分布式事务、数据容错、负载均衡
❌ 缺点:
-
配置复杂、学习成本高
-
轻量后台项目过于臃肿,性能有轻微损耗
-
运维成本高,不适合简单多数据源场景
3.4.3 适用场景
大数据量、分库分表、分布式架构、高并发中台级后台系统。
四、四种多数据源方案全方位对比(选型速查表)
| 实现方案 | 动态切换 | 代码侵入 | 事务支持 | 运维成本 | 适用场景 |
|---|---|---|---|---|---|
| 分包多SqlSession | ❌ 静态固定 | 中(分包约束) | 单库事务ok,跨库不支持 | 低 | 固定分库、简单后台 |
| 原生RoutingDataSource | ✅ 动态切换 | 高(手动编码) | 事务中无法切换 | 中 | 简单读写分离、无跨库事务 |
| Dynamic-Datasource框架 | ✅ 注解动态切换 | 极低(注解驱动) | 支持弱一致性跨库事务 | 极低 | 90%企业后台、多租户、读写分离 |
| Sharding-JDBC中间件 | ✅ 全自动代理 | 零侵入 | 支持强一致分布式事务 | 高 | 分库分表、高并发分布式系统 |
五、重难点:多数据源事务完整解决方案
5.1 核心问题:为什么原生 @Transactional 失效?
Spring 原生事务管理器 DataSourceTransactionManager仅绑定单个数据源,多库切换后,不同数据库连接不属于同一个事务上下文,A库提交成功、B库异常时,A库无法回滚,直接导致数据不一致。
5.2 三种多数据源事务方案(按一致性强弱排序)
5.2.1 方案1:Dynamic-Datasource 本地事务(最终一致性,轻量首选)
框架内置@DSTransactional 注解,替代原生事务注解,实现多数据源事务联动回滚,底层基于事务嵌套+上下文绑定,适合绝大多数后台业务。
实战代码:
@Service
public class OrderBusinessService {
// 多库事务统一管控
@DSTransactional
public void createOrder() {
// 操作主库
orderMapper.insert(order);
// 切换从库操作日志库
@DS("slave")
void saveLog(){
logMapper.insert(log);
}
saveLog();
// 模拟异常,全部回滚
int i = 1 / 0;
}
}
✅ 优点:零配置、极简、性能高、适配绝大多数后台业务
❌ 缺点:不支持跨服务分布式事务,仅本地多库
5.2.2 方案2:JTA+Atomikos 强一致性事务(2PC 本地多库强一致方案)
1、核心原理详解
JTA(Java Transaction API)是 Java 标准分布式事务规范,定义了跨资源(多数据库、消息队列)的事务统一管控标准,底层基于2PC(二阶段提交) 实现强数据一致性。SpringBoot3 原生舍弃老旧 Bitronix,默认适配 Atomikos 开源独立事务管理器,无需依赖应用服务器容器,可独立运行在微服务、单体项目中。
2PC 核心执行流程:
-
阶段一:准备阶段(Prepare):Atomikos 作为全局事务管理器,统一调度所有参与事务的多数据源,校验数据库连接可用性、SQL 合法性、资源锁定,所有数据源全部准备成功,才进入提交阶段;任意一个数据源准备失败,直接触发全局回滚。
-
阶段二:提交/回滚阶段(Commit/Rollback) :所有数据源准备成功,全局统一提交事务;任意节点准备失败、业务抛出异常,所有数据源统一回滚,严格保证多库数据要么全成功、要么全回滚。
核心特性:要求数据库必须支持 XA 协议 (MySQL、PostgreSQL、Oracle 主流数据库均原生支持),是单体项目多数据源无侵入、强一致的原生解决方案。
2、主流平台适配场景
-
适配 SpringBoot3 单体管理后台、老旧遗留系统改造
-
适用于低并发、强数据一致的核心业务(账单对账、数据归档、批量迁移)
-
无需部署中间件,纯代码配置即可落地,轻量化无运维成本
3、完整实战代码(SpringBoot3 最新适配)
第一步:引入 Atomikos 官方依赖
<!-- SpringBoot3 原生JTA-Atomikos分布式事务 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jta-atomikos</artifactId>
</dependency>
第二步:YAML 多数据源 XA 配置
spring:
datasource:
# 主库XA配置
master:
xa-url: jdbc:mysql://127.0.0.1:3306/db_master?useSSL=false&serverTimezone=Asia/Shanghai&allowMultiQueries=true
username: root
password: 123456
driver-class-name: com.mysql.cj.jdbc.Driver
# 从库XA配置
slave:
xa-url: jdbc:mysql://127.0.0.1:3306/db_slave?useSSL=false&serverTimezone=Asia/Shanghai&allowMultiQueries=true
username: root
password: 123456
driver-class-name: com.mysql.cj.jdbc.Driver
# Atomikos事务配置
jta:
atomikos:
properties:
max-timeout: 300
default-jta-timeout: 120
第三步:XA 多数据源+事务管理器配置类
@Configuration
public class AtomikosXaDataSourceConfig {
// 主库XA数据源
@Bean("masterDataSource")
@Primary
@ConfigurationProperties(prefix = "spring.datasource.master")
public AtomikosDataSourceBean masterDataSource() {
AtomikosDataSourceBean xaDataSource = new AtomikosDataSourceBean();
// MySQL XA驱动绑定
xaDataSource.setXaDataSourceClassName("com.mysql.cj.jdbc.MysqlXADataSource");
// 唯一资源标识,多数据源必须不同
xaDataSource.setUniqueResourceName("master-db");
// 连接池配置
xaDataSource.setMaxPoolSize(20);
xaDataSource.setMinPoolSize(5);
xaDataSource.setBorrowConnectionTimeout(60);
return xaDataSource;
}
// 从库XA数据源
@Bean("slaveDataSource")
@ConfigurationProperties(prefix = "spring.datasource.slave")
public AtomikosDataSourceBean slaveDataSource() {
AtomikosDataSourceBean xaDataSource = new AtomikosDataSourceBean();
xaDataSource.setXaDataSourceClassName("com.mysql.cj.jdbc.MysqlXADataSource");
xaDataSource.setUniqueResourceName("slave-db");
xaDataSource.setMaxPoolSize(20);
xaDataSource.setMinPoolSize(5);
xaDataSource.setBorrowConnectionTimeout(60);
return xaDataSource;
}
// 全局JTA事务管理器(统一管控多数据源)
@Bean
public JtaTransactionManager jtaTransactionManager() {
UserTransaction userTransaction = new UserTransactionImp();
UserTransactionManager transactionManager = new UserTransactionManager();
// 关闭强制关闭,避免事务中断
transactionManager.setForceShutdown(false);
JtaTransactionManager jtaTm = new JtaTransactionManager(userTransaction, transactionManager);
// 允许自定义事务隔离级别
jtaTm.setAllowCustomIsolationLevels(true);
return jtaTm;
}
}
第四步:业务层事务实战(多库联动回滚)
@Service
public class XaTransactionBusinessService {
@Autowired
private UserMapper userMapper; // 主库Mapper
@Autowired
private OperationLogMapper logMapper; // 从库Mapper
// 原生@Transactional生效,全局管控多数据源事务
@Transactional(rollbackFor = Exception.class)
public void multiDbTxTest() {
// 1.操作主库:新增用户数据
User user = new User();
user.setUsername("test-xa");
user.setAge(20);
userMapper.insert(user);
// 2.切换从库:新增操作日志
@DS("slave")
void saveLog(){
OperationLog log = new OperationLog();
log.setOperateContent("XA分布式事务测试");
logMapper.insert(log);
}
saveLog();
// 模拟异常:触发全局2PC回滚,主库、从库数据全部回滚
int error = 1 / 0;
}
}
4、深度优缺点分析
✅ 核心优点:
-
绝对强一致性:标准2PC协议,多数据源事务原子性百分百保障,无数据不一致风险
-
零中间件依赖:无需部署 Seata、MQ 等组件,纯本地配置即可实现分布式事务
-
原生适配 Spring 事务,
@Transactional直接生效,代码无侵入
❌致命缺点(生产核心避坑):
-
性能极差:2PC 存在长时间资源锁定、阻塞等待,高并发场景吞吐量暴跌
-
存在事务悬挂风险:准备阶段成功、提交阶段宕机,会导致数据库资源死锁占用
-
不支持跨服务事务,仅局限于本地多数据源,微服务架构完全不适用
-
长事务阻塞严重,不适合接口类、高并发后台业务
生产选型结论 :仅用于老旧单体系统、低并发离线任务、数据批量迁移,新项目、高并发业务禁止使用。
5.2.3 方案3:Seata 分布式事务(企业微服务/多数据源通用首选)
1、核心原理详解
Seata 是阿里开源的一站式分布式事务解决方案 ,彻底解决 JTA 性能短板,适配本地多数据源 + 跨微服务 双场景,是目前互联网企业、中台后台、SaaS 系统的绝对主流方案。生产默认采用 AT 模式(无侵入自动事务)。
Seata AT 模式核心原理(四阶段机制):
-
阶段1:开启事务:业务方法执行前,Seata 生成全局唯一 XID,绑定当前线程上下文,所有本地数据源操作自动归属同一全局事务。
-
阶段2:快照记录(Undo Log) :执行业务 SQL 时,Seata 自动拦截,前置查询数据库数据生成前置快照、后置记录更新后快照,存入 undo_log 日志表,无业务侵入。
-
阶段3:本地提交:单数据源本地事务优先提交,释放数据库锁,极大提升并发性能,规避 2PC 长阻塞问题。
-
阶段4:全局决议:所有分支执行成功,全局事务提交,异步删除 undo_log 日志;任意分支异常,全局触发回滚,通过 undo_log 快照还原数据,保证多库数据一致。
核心优势:牺牲极小最终一致性延迟,换取超高并发性能,无锁阻塞、适配高并发后台业务,完美兼容多数据源动态切换场景。
2、主流平台整合方案
当前企业主流技术栈整合:SpringBoot3 + Dynamic-Datasource4.3.0 + Seata1.7.x + Nacos
-
Nacos:托管 Seata 配置、多数据源动态配置,实现热更新
-
Dynamic-Datasource:负责多数据源注解切换、上下文管理
-
Seata:全局管控多库事务、跨服务事务,保障数据一致性
-
适配所有中台后台、SaaS多租户、微服务架构系统
3、完整实战整合代码(可直接上线)
第一步:核心依赖引入
<!-- 动态多数据源 -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>dynamic-datasource-spring-boot-starter</artifactId>
<version>4.3.0</version>
</dependency>
<!-- Seata SpringBoot3 适配依赖 -->
<dependency>
<groupId>io.seata</groupId>
<artifactId>seata-spring-boot-starter</artifactId>
<version>1.7.2</version>
</dependency>
第二步:YAML 统一配置(Nacos 可托管)
spring:
# 多数据源配置
datasource:
dynamic:
primary: master
strict: false
datasource:
master:
url: jdbc:mysql://127.0.0.1:3306/db_master?useSSL=false&serverTimezone=Asia/Shanghai
username: root
password: 123456
driver-class-name: com.mysql.cj.jdbc.Driver
slave:
url: jdbc:mysql://127.0.0.1:3306/db_slave?useSSL=false&serverTimezone=Asia/Shanghai
username: root
password: 123456
driver-class-name: com.mysql.cj.jdbc.Driver
# Seata全局事务配置
seata:
application-id: admin-multi-ds
tx-service-group: default_tx_group
service:
vgroup-mapping:
default_tx_group: default
config:
type: nacos
registry:
type: nacos
第三步:数据库前置准备(所有数据源执行)
所有参与事务的数据库(master、slave)必须新建 undo_log 表,Seata 依赖该表实现快照回滚:
CREATE TABLE IF NOT EXISTS `undo_log`
(
`id` BIGINT(20) NOT NULL AUTO_INCREMENT COMMENT '主键ID',
`branch_id` BIGINT(20) NOT NULL COMMENT '分支事务ID',
`xid` VARCHAR(100) NOT NULL COMMENT '全局事务ID',
`context` VARCHAR(128) NOT NULL COMMENT '上下文',
`rollback_info` LONGBLOB NOT NULL COMMENT '回滚快照信息',
`log_status` INT(11) NOT NULL COMMENT '日志状态 0:正常 1:已回滚',
`log_created` DATETIME NOT NULL COMMENT '创建时间',
`log_modified` DATETIME NOT NULL COMMENT '修改时间',
PRIMARY KEY (`id`),
UNIQUE KEY `ux_undo_log` (`xid`,`branch_id`)
) ENGINE = InnoDB
DEFAULT CHARSET = utf8mb4 COMMENT = 'Seata事务回滚日志表';
第四步:业务层多数据源事务实战(核心生产写法)
@Service
public class SeataMultiDsTransactionService {
@Autowired
private UserMapper userMapper;
@Autowired
private OrderLogMapper orderLogMapper;
// Seata全局事务注解,替代原生事务,管控多数据源+跨服务事务
@GlobalTransactional(rollbackFor = Exception.class)
public void businessMultiDbOperate() {
// 1.操作主库:新增订单核心数据
User user = new User();
user.setUsername("seata-test-user");
userMapper.insert(user);
// 2.动态切换从库:新增订单日志
@DS("slave")
void saveOrderLog(){
OrderLog log = new OrderLog();
log.setOrderNo("TX20260625001");
log.setOperateDesc("多数据源Seata事务执行");
orderLogMapper.insert(log);
}
saveOrderLog();
// 模拟业务异常,全局事务回滚,主从库数据全部撤销
// int i = 1 / 0;
}
}
4、深度优缺点 & 生产适配场景
✅ 核心优点:
-
高性能无阻塞:基于 AT 模式,规避 2PC 长事务阻塞,并发性能接近单库事务
-
双场景适配:同时支持本地多数据源事务 、跨微服务分布式事务
-
代码极低侵入:仅需
@GlobalTransactional注解,无需修改数据源逻辑 -
适配动态数据源:完美兼容 Dynamic-Datasource 动态切换,无事务锁定问题
-
生态完善:支持 Nacos 热更新、监控告警、事务日志溯源,适配企业中台架构
❌ 缺点:
-
存在极小概率空回滚、幂等性问题(生产可通过兜底配置规避)
-
需要部署 Seata Server 服务,有少量运维成本
5.3、主流方案最终选型对比(面试+生产必背)
| 事务方案 | 一致性级别 | 并发性能 | 运维成本 | 适用架构 | 生产推荐度 |
|---|---|---|---|---|---|
| @DSTransactional(框架本地) | 最终一致 | 极高 | 零成本 | 单体轻量后台 | ⭐⭐⭐⭐⭐(普通业务首选) |
| JTA+Atomikos(2PC) | 强一致 | 极低 | 低成本 | 老旧单体、离线任务 | ⭐⭐(新项目禁用) |
| Seata AT | 弱强一致 | 高 | 中 | 微服务、中台、核心业务 | ⭐⭐⭐⭐⭐(分布式标配) |
基于 XA 协议二阶段提交,实现多数据源强一致性事务,所有库同时成功、同时回滚。
✅ 优点:数据强一致、无数据不一致风险 ❌ 缺点:性能差、配置繁琐、长事务阻塞、不适合高并发
5.4 业务选型口诀
-
普通后台、非核心资金业务 :优先
@DSTransactional轻量事务 -
核心账务、强一致业务:使用 Seata AT 分布式事务
-
老旧单体系统、极致强一致:选用 JTA+Atomikos(不推荐新项目)
六、生产多数据源避坑总结
-
禁止原生 @Transactional 做多库事务,百分百出现数据不一致
-
事务内谨慎切换数据源:原生路由数据源事务中锁定,框架版需用专属事务注解
-
读写分离禁止写操作走从库:通过注解严格区分读写数据源
-
动态数据源必须配置默认库,避免上下文清空导致空指针
-
高并发场景禁用JTA,性能瓶颈严重,优先Seata/框架事务
七、全文总结
1、轻量化后台、快速开发:首选Dynamic-Datasource 注解动态数据源,简洁高效、事务可控;
2、简单固定分库、无动态切换:选用 分包多数据源,原生稳定零依赖;
3、大数据量分库分表、分布式架构:选用 Sharding-JDBC 中间件方案;
4、多库事务优先框架自带 @DSTransactional ,核心分布式业务接入 Seata,彻底解决数据一致性问题。