技术派自定义多数据源进阶(👍强烈推荐)
选中新版正文中的对应文字,然后点“定位到这里”。
之前的一篇介绍了技术派是如何实现自定义的动态数据源切换的技术方案,但是当时提出了几个问题,我们再来瞅一下
✅技术派自定义多数据源方案(👍强烈推荐) 《技术派中的自定义多数据源实现方案(已完成)》 密码:die6
上文的方案中,有几个明显的缺陷
- 如果一个方法上有数据源选择注解,但是内部开了子线程做异步处理,那么上下文存储的数据源会失效
- 一个方法上指定了数据源,它又调用其他有也指定了数据源的方法,当前的方案会存在数据源的选择冲突
- druid数据源怎么兼容?
接下来我们基于上面的问题,来升级我们的实现方案
支持嵌套的数据源选择方案
前面提出的一个非常大的问题就是再整个链路中,只支持选择一次的数据源,显然这种方式缺陷比较大,也很容易出现问题;
若我们希望实现在选择了一个数据源之后,在执行某个代码片段时,还可以继续再选择其他的数据源,那么应该怎么实现呢?
首先我们来看一下之前的实现方案

在执行sql时,从上下文中获取当前选中的数据源,前面设计的上下文直接使用线程上线文保存
public class DsContextHolder {
/**
* 使用继承的线程上下文,支持异步时选择传递
*/
private static final ThreadLocal CONTEXT_HOLDER = new InheritableThreadLocal<>();
}
从上面的这个实现来看,上下文赋值只能有一次,当我们希望可以实现标题的效果,自然我们应该想到的数据结构就是栈 -- 后进先出
我们定义一个DsNode节点来存储选中的数据源,区别于之前的String,它除了记录选中的数据源之外,还记录前一次选中的数据源
public static class DsNode {
DsNode pre;
String ds;
public DsNode(DsNode parent, String ds) {
pre = parent;
this.ds = ds;
}
}
然后将线程上下文存储的替换为DsNode
/**
* 使用继承的线程上下文,支持异步时选择传递
* 使用DsNode,支持链式的数据源切换,如最外层使用master数据源,内部某个方法使用slave数据源;但是请注意,对于事务的场景,不要交叉
*/
private static final ThreadLocal CONTEXT_HOLDER = new InheritableThreadLocal<>();
接下来就需要重点看一下写入当前选中的数据源的逻辑
- 每当有一个新的数据源选中时,新创建一个DsNode,并重新加入ThreadLocal
- 之前的上下文中的DsNode将作为新的DsNode的上一个节点
public static void set(String dbType) {
DsNode current = CONTEXT_HOLDER...未能定位到原文的划线
已加入星球,可直接知识星球授权登录
二哥编程星球目前包含:
企业级Agent工作流编排项目PaiFlow
Vibe Coding版本的PaiAgent
派聪明RAG AI知识库Java版本+Go版本
微服务 PmHub、技术派、MYDB
求职派JobClaw(OpenClaw/Hermes架构
PaiCLI(类似Claude Code的Agent
派简历(代码已完成)
等实战项目。
企业级Agent工作流编排项目PaiFlow
Vibe Coding版本的PaiAgent
派聪明RAG AI知识库Java版本+Go版本
微服务 PmHub、技术派、MYDB
求职派JobClaw(OpenClaw/Hermes架构
PaiCLI(类似Claude Code的Agent
派简历(代码已完成)
等实战项目。
1. 微信扫右侧的优惠券加入知识星球
2. 解锁星球的实战项目教程和源码: 项目源码+教程获取
真诚点赞 诚不我欺
回复