Java鎖競(jìng)爭(zhēng)導(dǎo)致sql慢日志原因分析
線(xiàn)上在同步用戶(hù)時(shí),經(jīng)常出現(xiàn)簡(jiǎn)單sql的慢日志。根據(jù)方法找到代碼,發(fā)現(xiàn)方法內(nèi)使用redisson進(jìn)行鎖操作,waiTime和leaseTime都為3秒,數(shù)據(jù)庫(kù)操作比較簡(jiǎn)單,只是一個(gè)簡(jiǎn)單的用戶(hù)更新操作。代碼簡(jiǎn)化后如下
@Override
@Transactional(rollbackFor = Exception.class)
public LiveMemberResponseDTO becomeStudentNotQueryOrder(LiveBecomeStudentForOrderRequestDTO requestDTO) {
EduUserEntity user = eduUserService.syncLocalByAccount(requestDTO.getOrderAccountId(), UserRegisterChannel.LIVE_APPLY);
EduUserEntity applyUser = eduUserService.syncLocalByAccount(requestDTO.getApplyAccountId(), UserRegisterChannel.LIVE_APPLY);
...
...
...
}
調(diào)用了更新方法
@Override
@Lock(waitTime = 10000, leaseTime = 3000, value = RedisConstant.USER_SYNC_LOCAL, key = "#accountId")
public EduUserEntity syncLocalByAccount(String accountId, String mobile, String fullName, String source, UserRegisterChannel registerChannel) {
EduUserEntity eduUserEntity = queryUsersByAccountId(accountId);
boolean updateFlag = false;
....
....
....//判斷是否需要更新
if (updateFlag) {
saveOrUpdate(eduUserEntity);
}
return eduUserEntity;
}由于這里事務(wù)里面嵌套了redis鎖,并且涉及到更新表,可能會(huì)有死鎖的情況。通過(guò)在獲取鎖的地方打上地址獲取到以下日志

可以看到[Thread-13]在等待了三秒后才獲取到redis,根據(jù)獲取鎖的時(shí)機(jī),列出表格
| 事務(wù)A(Thread-13) | 事務(wù)B(Thread-14) |
|---|---|
| 獲取redis鎖 | |
| 獲取db鎖 | |
| 釋放redis鎖 | |
| 獲取redis鎖 | |
| 嘗試獲取db鎖 | |
| 嘗試獲取redis鎖 | |
| 等待三秒 | |
| redis鎖超時(shí),釋放redis鎖 | |
| 成功獲取redis鎖 | |
| 完成業(yè)務(wù) | |
| 釋放redis和db鎖 | |
| 獲取db鎖 |
這是由于兩次更新user表過(guò)程中,使用了一個(gè)事務(wù)A,導(dǎo)致事務(wù)B來(lái)獲取db行鎖的時(shí)候,被事務(wù)A阻塞。但在被事務(wù)A阻塞前,已經(jīng)獲取到了redis鎖,所以導(dǎo)致事務(wù)A在獲取第二次更新的redis鎖的時(shí)候被阻塞,造成了死鎖。

最終導(dǎo)致,redis鎖超時(shí),日志方面體現(xiàn)為慢sql,因?yàn)槭聞?wù)B的sql等待了三秒才拿到鎖。
這種情況是因?yàn)槭聞?wù)和redis鎖的嵌套導(dǎo)致,所以指定更新方法的事務(wù)傳播等級(jí)為PROPAGATION_REQUIRED_NEW,不管外層是否存著事務(wù),都開(kāi)啟新事務(wù)。
修改后代碼
@Override
@Lock(waitTime = 10000, leaseTime = 3000, value = RedisConstant.USER_SYNC_LOCAL, key = "#accountId")
//這里開(kāi)啟新事務(wù)
@Transactional(propagation = Propagation.REQUIRES_NEW, rollbackFor = Exception.class)
public EduUserEntity syncLocalByAccount(String accountId, String mobile, String fullName, String source, UserRegisterChannel registerChannel) {
EduUserEntity eduUserEntity = queryUsersByAccountId(accountId);
boolean updateFlag = false;
....
....
....//判斷是否需要更新
if (updateFlag) {
saveOrUpdate(eduUserEntity);
}
return eduUserEntity;
}聲明式事務(wù)使用很簡(jiǎn)單,可以自動(dòng)幫我們進(jìn)行事務(wù)的開(kāi)啟、提交以及回滾等操作,但是事務(wù)的顆粒度是整個(gè)方法,無(wú)法進(jìn)行精細(xì)化控制。在使用過(guò)程中要注意事務(wù)的范圍與其他中間件的交互,通過(guò)指定適當(dāng)?shù)膫鞑サ燃?jí)來(lái)達(dá)到效果。
到此這篇關(guān)于Java鎖競(jìng)爭(zhēng)導(dǎo)致sql慢日志原因分析的文章就介紹到這了,更多相關(guān)Java sql慢日志內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
java中的構(gòu)造函數(shù)什么時(shí)候被調(diào)用執(zhí)行
這篇文章主要介紹了java中的構(gòu)造函數(shù)什么時(shí)候被調(diào)用執(zhí)行問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-03-03
Spring Cloud Config實(shí)現(xiàn)分布式配置中心
這篇文章主要介紹了Spring Cloud Config實(shí)現(xiàn)分布式配置中心,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-04-04
Java解析zip文件,并識(shí)別壓縮包里面的文件轉(zhuǎn)換成可操作的IO流方式
這篇文章主要介紹了Java解析zip文件,并識(shí)別壓縮包里面的文件轉(zhuǎn)換成可操作的IO流方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-08-08
Java反射機(jī)制原理、Class獲取方式以及應(yīng)用場(chǎng)景詳解
反射機(jī)制是JAVA的核心知識(shí)點(diǎn)之一,大多數(shù)框架的實(shí)現(xiàn)原理就是利用了反射機(jī)制,掌握反射機(jī)制會(huì)使你學(xué)習(xí)框架更加輕松高效,這篇文章主要給大家介紹了關(guān)于Java反射機(jī)制原理、Class獲取方式以及應(yīng)用場(chǎng)景的相關(guān)資料,需要的朋友可以參考下2022-04-04
SpringBoot自定義Starter實(shí)現(xiàn)流程詳解
SpringBoot中的starter是一種非常重要的機(jī)制,能夠拋棄以前繁雜的配置,將其統(tǒng)一集成進(jìn)starter,應(yīng)用者只需要在maven中引入starter依賴(lài),SpringBoot就能自動(dòng)掃描到要加載的信息并啟動(dòng)相應(yīng)的默認(rèn)配置。starter讓我們擺脫了各種依賴(lài)庫(kù)的處理,需要配置各種信息的困擾2022-09-09
Java RSA加密解密實(shí)現(xiàn)方法分析【附BASE64 jar包下載】
這篇文章主要介紹了Java RSA加密解密實(shí)現(xiàn)方法,結(jié)合實(shí)例形式分析了java基于第三方類(lèi)庫(kù)javabase64-1.3.1.jar實(shí)現(xiàn)RSA加密解密功能的具體步驟與相關(guān)操作技巧,需要的朋友可以參考下2017-10-10
手把手教你SpringBoot快速集成Swagger的配置過(guò)程
這篇文章主要介紹了手把手教你SpringBoot快速集成Swagger的配置過(guò)程,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-02-02

