
Dynamic DataSource 的连接流转全过程包含三个核心场景图中内容说明① 写入主库createOrder()—DS(master) Transactional步骤流转1-4Client → OrderService →DS AOP 切面→ContextHolder.set(master)→ proceed5-11TX Interceptor开启事务 → DynamicDataSource 从 ContextHolder 读取 key → 向HikariCP(master)获取连接 → 绑定到当前线程12MyBatis 通过绑定的 master 连接执行INSERT13-16commit → 归还连接到 HikariPool →ContextHolder.clear()→ 返回结果核心机制DS在方法入口通过 AOP 把数据源标识写入 ThreadLocalDynamicDataSource 在getConnection()时从 ThreadLocal 读取并路由到对应的 HikariCP。② 读取从库getOrderById()—DS(slave)流程与 ① 类似但没有事务绑定每次调用独立获取/归还 slave 连接实现读写分离。③ 查询报表库queryReport()—DS(report)独立路由到 report 数据源业务隔离不影响主库性能。关键设计要点图中标注要点说明ThreadLocal 隔离每个线程独立存储数据源标识互不干扰方法结束 clear()防止 ThreadLocal 污染下一个请求尤其线程池场景事务绑定连接Transactional一旦绑定 master 连接整个事务内不可切换⚠️ 跨库陷阱同一事务内DS(report)会被压制仍走 master图中底部红色警告跨库事务的正确解决方案// 方案1拆成独立事务DS(master)Transactional(propagationPropagation.REQUIRES_NEW)publicvoidcreateOrder(Orderorder){...}DS(report)Transactional(propagationPropagation.REQUIRES_NEW)publicvoidwriteReport(){...}// 方案2使用 dynamic-datasource 的 DSTransactional弱一致性DSTransactionalpublicvoidcrossDbOperation(){...}PlantUML 源码文件也已保存在沙盒中dynamic-datasource-sequence.puml你可以在本地安装 PlantUML 后渲染为矢量图方便修改和二次编辑。