欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Java鎖競爭導(dǎo)致sql慢日志原因分析

 更新時間:2022年11月20日 15:40:18   作者:古柏樹下  
這篇文章主要介紹了Java鎖競爭導(dǎo)致sql慢的日志原因分析,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習或者工作具有一定的參考學(xué)習價值,需要的朋友們下面隨著小編來一起學(xué)習吧

線上在同步用戶時,經(jīng)常出現(xiàn)簡單sql的慢日志。根據(jù)方法找到代碼,發(fā)現(xiàn)方法內(nèi)使用redisson進行鎖操作,waiTime和leaseTime都為3秒,數(shù)據(jù)庫操作比較簡單,只是一個簡單的用戶更新操作。代碼簡化后如下

@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鎖,并且涉及到更新表,可能會有死鎖的情況。通過在獲取鎖的地方打上地址獲取到以下日志

可以看到[Thread-13]在等待了三秒后才獲取到redis,根據(jù)獲取鎖的時機,列出表格

事務(wù)A(Thread-13)事務(wù)B(Thread-14)
獲取redis鎖
獲取db鎖
釋放redis鎖
獲取redis鎖
嘗試獲取db鎖
嘗試獲取redis鎖
等待三秒
redis鎖超時,釋放redis鎖
成功獲取redis鎖
完成業(yè)務(wù)
釋放redis和db鎖
獲取db鎖

這是由于兩次更新user表過程中,使用了一個事務(wù)A,導(dǎo)致事務(wù)B來獲取db行鎖的時候,被事務(wù)A阻塞。但在被事務(wù)A阻塞前,已經(jīng)獲取到了redis鎖,所以導(dǎo)致事務(wù)A在獲取第二次更新的redis鎖的時候被阻塞,造成了死鎖。

最終導(dǎo)致,redis鎖超時,日志方面體現(xiàn)為慢sql,因為事務(wù)B的sql等待了三秒才拿到鎖。

這種情況是因為事務(wù)和redis鎖的嵌套導(dǎo)致,所以指定更新方法的事務(wù)傳播等級為PROPAGATION_REQUIRED_NEW,不管外層是否存著事務(wù),都開啟新事務(wù)。

修改后代碼

@Override
@Lock(waitTime = 10000, leaseTime = 3000, value = RedisConstant.USER_SYNC_LOCAL, key = "#accountId")
//這里開啟新事務(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ù)使用很簡單,可以自動幫我們進行事務(wù)的開啟、提交以及回滾等操作,但是事務(wù)的顆粒度是整個方法,無法進行精細化控制。在使用過程中要注意事務(wù)的范圍與其他中間件的交互,通過指定適當?shù)膫鞑サ燃墎磉_到效果。

到此這篇關(guān)于Java鎖競爭導(dǎo)致sql慢日志原因分析的文章就介紹到這了,更多相關(guān)Java sql慢日志內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • java實現(xiàn)水波紋擴散效果

    java實現(xiàn)水波紋擴散效果

    這篇文章主要為大家詳細介紹了java實現(xiàn)水波紋擴散效果,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2019-01-01
  • SpringBoot使用JUL實現(xiàn)日志記錄功能

    SpringBoot使用JUL實現(xiàn)日志記錄功能

    在SpringBoot中,我們可以使用多種日志框架進行日志記錄,其中,JUL(Java Util Logging)是Java平臺自帶的日志框架,它提供了簡單的 API 和配置,可以輕松地進行日志記錄,本文將介紹如何在 SpringBoot中使用JUL進行日志記錄,并提供示例代碼
    2023-06-06
  • Java中Static關(guān)鍵字的五種用法詳解

    Java中Static關(guān)鍵字的五種用法詳解

    這篇文章主要介紹了Java中static的五種用法:修飾成員變量,修飾成員方法,修飾內(nèi)部類,靜態(tài)代碼塊,靜態(tài)導(dǎo)包,想詳細了解的小伙伴可以參考閱讀本文
    2023-03-03
  • Java Array.sort()源碼分析講解

    Java Array.sort()源碼分析講解

    Arrays類中有一個sort()方法,該方法是Arrays類的靜態(tài)方法,在需要對數(shù)組進行排序時,非常的好用。但是sort()的參數(shù)有好幾種,下面我就為大家一一介紹,這幾種形式的用法
    2022-08-08
  • Java中Stringbuilder和正則表達式示例詳解

    Java中Stringbuilder和正則表達式示例詳解

    Java語言為字符串連接運算符(+)提供特殊支持,并為其他對象轉(zhuǎn)換為字符串,字符串連接是通過StringBuilder(或StringBuffer)類及其append方法實現(xiàn)的,這篇文章主要給大家介紹了關(guān)于Java中Stringbuilder和正則表達式的相關(guān)資料,需要的朋友可以參考下
    2024-02-02
  • 詳解Java8如何使用Lambda表達式進行比較

    詳解Java8如何使用Lambda表達式進行比較

    Lambda表達式,也可稱為閉包,是java8的新特性,作用是取代大部分內(nèi)部類,優(yōu)化java代碼結(jié)構(gòu),讓代碼變得更加簡潔緊湊。本文將利用Lambda表達式進行排序比較,需要的可以參考一下
    2022-01-01
  • Java上傳文件錯誤java.lang.NoSuchMethodException的解決辦法

    Java上傳文件錯誤java.lang.NoSuchMethodException的解決辦法

    今天小編就為大家分享一篇關(guān)于Java上傳文件錯誤java.lang.NoSuchMethodException的解決辦法,小編覺得內(nèi)容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧
    2019-01-01
  • Springboot中如何自定義監(jiān)聽器

    Springboot中如何自定義監(jiān)聽器

    這篇文章主要介紹了Springboot中自定義監(jiān)聽器,自定義事件需要繼承ApplicationEvent類,并添加一個構(gòu)造函數(shù),用于接收事件源對象,本文通過示例代碼給大家介紹的非常詳細,感興趣的朋友一起看看吧
    2024-07-07
  • 使用Java實現(xiàn)查找并移除字符串中的Emoji

    使用Java實現(xiàn)查找并移除字符串中的Emoji

    Emoji 實際上是 UTF-8 (Unicode) 字符集上的特殊字符,這篇文章主要介紹了如何使用Java實現(xiàn)查找并移除字符串中的Emoji,感興趣的可以了解下
    2024-03-03
  • 如何重寫hashcode和equals方法

    如何重寫hashcode和equals方法

    這篇文章主要介紹了如何重寫hashcode和equals方法,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-06-06

最新評論