網(wǎng)站首頁 編程語言 正文
文章目錄
- AOP+注解方式實(shí)現(xiàn)多數(shù)據(jù)源原理
- 可能遇到的問題
- 情景1:指定數(shù)據(jù)源的請求中發(fā)生報(bào)錯
- 情景2:指定數(shù)據(jù)源的請求中使用新的線程
AOP+注解方式實(shí)現(xiàn)多數(shù)據(jù)源原理
通過ThreadLocal的線程隔離性將設(shè)線程與數(shù)據(jù)源ID進(jìn)行綁定:
- 若不設(shè)置則使用默認(rèn)數(shù)據(jù)源
- 若設(shè)置則使用該數(shù)據(jù)源ID對應(yīng)的數(shù)據(jù)源(注意:使用完后需要清除該數(shù)據(jù)源ID)
可能遇到的問題
情景1:指定數(shù)據(jù)源的請求中發(fā)生報(bào)錯
問題描述:指定數(shù)據(jù)源的請求中發(fā)生報(bào)錯,后面未指定數(shù)據(jù)源的請求卻使用了該指定數(shù)據(jù)源(應(yīng)該使用默認(rèn)數(shù)據(jù)源)。
代碼:
@Slf4j
@Aspect
@Order(-2)
@Component
public class DataSourceAspect {
@Pointcut("@annotation(com.joker.datasource.aopannotation.DataSource) || @within(com.joker.datasource.aopannotation.DataSource)")
public void run(){
}
@Around("run()")
public Object around(ProceedingJoinPoint point) throws Throwable {
MethodSignature signature = (MethodSignature) point.getSignature();
// 方法上獲取
// AnnotatedElementUtils.hasAnnotation()
DataSource dataSource = AnnotationUtils.findAnnotation(signature.getMethod(), DataSource.class);
if (Objects.isNull(dataSource)) {
// 類上獲取
dataSource = AnnotationUtils.findAnnotation(signature.getDeclaringType(), DataSource.class);
}
// 設(shè)置數(shù)據(jù)源
DynamicDataSourceContextHolder.setDataSourceType(dataSource.value().name());
Object obj = point.proceed();
// 清除數(shù)據(jù)源
DynamicDataSourceContextHolder.clearDataSourceType();
return obj;
}
}
問題分析:
- 指定數(shù)據(jù)源的請求中發(fā)生報(bào)錯,導(dǎo)致清除數(shù)據(jù)源ID未執(zhí)行,當(dāng)前線程thread1仍然綁定了該數(shù)據(jù)源;
- 由于接口請求使用的線程是通過線程池來管理的,后續(xù)該線程thread1可能會繼續(xù)分配給其它請求使用
- 如果后續(xù)請求使用了該線程thread1且未指定數(shù)據(jù)源,使用的仍然是前面綁定的數(shù)據(jù)源,導(dǎo)致使用錯數(shù)據(jù)源(原本應(yīng)該使用默認(rèn)數(shù)據(jù)源)
- 但如果后續(xù)請求使用了該線程thread1但指定了數(shù)據(jù)源,則不會有問題
情景2:指定數(shù)據(jù)源的請求中使用新的線程
問題描述:指定數(shù)據(jù)源的請求中使用新的線程,導(dǎo)致指定數(shù)據(jù)源無效,使用的是默認(rèn)數(shù)據(jù)源。
問題分析:因?yàn)閿?shù)據(jù)源是和線程綁定的,即使在當(dāng)前線程綁定了指定數(shù)據(jù)源,但如果在請求中使用了新的線程,新線程是沒有綁定數(shù)據(jù)源的(默認(rèn)使用默認(rèn)數(shù)據(jù)源)。使用新線程的一下場景:
- 使用了new Thread()創(chuàng)建的新線程,在新線程中使用數(shù)據(jù)源
- 使用了線程池,通過線程池中的線程來使用數(shù)據(jù)源
- 使用了Java8中l(wèi)ist.parallelStream()來并行處理(多線程處理),處理過程中使用數(shù)據(jù)
原文鏈接:https://blog.csdn.net/JokerLJG/article/details/131406803
- 上一篇:沒有了
- 下一篇:沒有了
相關(guān)推薦
- 2022-07-06 C#中的SQLCommand命令與DbTransaction事務(wù)處理_C#教程
- 2022-04-22 qiankun框架下使用el-select或者分頁報(bào)錯Failed to execute ‘getC
- 2023-07-18 SpringBoot中線程池初始化,并且可配置線程池參數(shù)
- 2022-09-14 iOS開發(fā)多線程下全局變量賦值崩潰原理詳解_IOS
- 2022-09-06 C語言用函數(shù)指針實(shí)現(xiàn)一個特別的計(jì)算器_C 語言
- 2022-11-30 詳解如何在Go語言中循環(huán)數(shù)據(jù)結(jié)構(gòu)_Golang
- 2022-10-08 如何在React項(xiàng)目中引入字體文件并使用詳解_React
- 2022-09-15 C#中DateTime的時間加減法操作小結(jié)_C#教程
- 欄目分類
-
- 最近更新
-
- window11 系統(tǒng)安裝 yarn
- 超詳細(xì)win安裝深度學(xué)習(xí)環(huán)境2025年最新版(
- Linux 中運(yùn)行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎(chǔ)操作-- 運(yùn)算符,流程控制 Flo
- 1. Int 和Integer 的區(qū)別,Jav
- spring @retryable不生效的一種
- Spring Security之認(rèn)證信息的處理
- Spring Security之認(rèn)證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權(quán)
- redisson分布式鎖中waittime的設(shè)
- maven:解決release錯誤:Artif
- restTemplate使用總結(jié)
- Spring Security之安全異常處理
- MybatisPlus優(yōu)雅實(shí)現(xiàn)加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務(wù)發(fā)現(xiàn)-Nac
- Spring Security之基于HttpR
- Redis 底層數(shù)據(jù)結(jié)構(gòu)-簡單動態(tài)字符串(SD
- arthas操作spring被代理目標(biāo)對象命令
- Spring中的單例模式應(yīng)用詳解
- 聊聊消息隊(duì)列,發(fā)送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠(yuǎn)程分支