spring-boot-starter-dynamic-datasource

 * 为了支持嵌套切换,如ABC三个service都是不同的数据源
 * 其中A的某个业务要调B的方法,B的方法需要调用C的方法。一级一级调用切换,形成了链。
 * 传统的只设置当前线程的方式不能满足此业务需求,必须使用栈,后进先出。

[18 tools called]

基于对 aiyong-spring-boot-starter-dynamic-datasource 模块的源码深度分析,我来为你详细讲解多数据源的原理、使用方式和事务处理机制。

一、多数据源实现原理

1. 核心架构设计

这个多数据源实现基于Spring的AbstractRoutingDataSource,采用了以下关键设计:

核心组件

数据结构

// 存储所有数据源
private final Map<String, DataSource> dataSourceMap = new ConcurrentHashMap<>();
// 分组数据源,支持负载均衡
private final Map<String, GroupDataSource> groupDataSources = new ConcurrentHashMap<>();

2. 数据源切换流程

graph TD
    A["Method Call"] --> B["@DS Annotation"]
    B --> C["AOP Interceptor"]
    C --> D["Parse DataSource Key"]
    D --> E["Push to ThreadLocal Stack"]
    E --> F["determineDataSource()"]
    F --> G["Get Key from ThreadLocal"]
    G --> H{"Is Group DataSource?"}
    H -->|"Yes"| I["GroupDataSource Load Balance"]
    H -->|"No"| J["Get from dataSourceMap"]
    I --> K["Return DataSource"]
    J --> K
    K --> L["Execute Business Logic"]
    L --> M["Method End"]
    M --> N["Pop ThreadLocal Stack"]

关键实现代码

@Override
protected String getPrimary() {
    return primary;
}

@Override
public DataSource determineDataSource() {
    String dsKey = DynamicDataSourceContextHolder.peek();
    return getDataSource(dsKey);
}

3. ThreadLocal栈设计