基于Spring的多数据源管理实战

一、多数据源业务场景(管理后台核心场景)

先明确落地场景,避免盲目选型:

  1. 业务分库:用户库、订单库、日志库、配置库独立拆分

  2. 读写分离:主库写、从库读,提升后台查询吞吐量

  3. 多租户隔离:SaaS后台,不同租户独立数据库

  4. 外部数据对接:后台对接第三方业务库、历史迁移库

  5. 数据同步/归档:生产库查询、归档库写入备份数据


二、目前主流4种多数据源实现方案(2026最新选型)

从简单到复杂、从静态到动态、从原生到框架 排序,覆盖所有企业落地方式:

  1. 方式一:分包多数据源(多SqlSessionFactory 静态固定)

  2. 方式二:Spring 原生 AbstractRoutingDataSource 动态路由

  3. 方式三:MyBatis-Plus Dynamic-Datasource 注解动态切换(企业首选)

  4. 方式四:中间件代理(Sharding-JDBC/MyCat 分布式层方案)


三、四种方案原理、优缺点、适用场景+完整代码

3.1 方式一:分包多数据源(静态多SqlSessionFactory)

3.1.1 实现原理

通过 @MapperScan 区分不同 Mapper 包路径,分别创建独立的 DataSourceSqlSessionFactoryTransactionManager,不同包下的 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 核心执行流程:

  1. 阶段一:准备阶段(Prepare):Atomikos 作为全局事务管理器,统一调度所有参与事务的多数据源,校验数据库连接可用性、SQL 合法性、资源锁定,所有数据源全部准备成功,才进入提交阶段;任意一个数据源准备失败,直接触发全局回滚。

  2. 阶段二:提交/回滚阶段(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. 阶段1:开启事务:业务方法执行前,Seata 生成全局唯一 XID,绑定当前线程上下文,所有本地数据源操作自动归属同一全局事务。

  2. 阶段2:快照记录(Undo Log) :执行业务 SQL 时,Seata 自动拦截,前置查询数据库数据生成前置快照、后置记录更新后快照,存入 undo_log 日志表,无业务侵入。

  3. 阶段3:本地提交:单数据源本地事务优先提交,释放数据库锁,极大提升并发性能,规避 2PC 长阻塞问题。

  4. 阶段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(不推荐新项目)


六、生产多数据源避坑总结

  1. 禁止原生 @Transactional 做多库事务,百分百出现数据不一致

  2. 事务内谨慎切换数据源:原生路由数据源事务中锁定,框架版需用专属事务注解

  3. 读写分离禁止写操作走从库:通过注解严格区分读写数据源

  4. 动态数据源必须配置默认库,避免上下文清空导致空指针

  5. 高并发场景禁用JTA,性能瓶颈严重,优先Seata/框架事务


七、全文总结

1、轻量化后台、快速开发:首选Dynamic-Datasource 注解动态数据源,简洁高效、事务可控;

2、简单固定分库、无动态切换:选用 分包多数据源,原生稳定零依赖;

3、大数据量分库分表、分布式架构:选用 Sharding-JDBC 中间件方案;

4、多库事务优先框架自带 @DSTransactional ,核心分布式业务接入 Seata,彻底解决数据一致性问题。