innodb行鎖:兩階段鎖協(xié)議與死鎖預(yù)防

先放個網(wǎng)絡(luò)美女提提神

MySQL的行級鎖是由各個引擎自己實現(xiàn)的,innodb支持行級鎖但MyISAM卻不支持,這也是innodb更受青睞的原因之一。
想要高效使用innodb的行級鎖,必須要熟悉兩階段鎖協(xié)議和死鎖預(yù)防。

兩階段鎖協(xié)議

  • 定義
    事務(wù)執(zhí)行時,在運(yùn)行到需要加鎖的語句時加鎖,但不是對應(yīng)語句執(zhí)行完了就釋放鎖,而是等到commit時才會釋放鎖。


    圖1 兩階段鎖協(xié)議實例

    如圖1所示,session1在t1時刻對id=1的行加鎖了。在t4時刻session2想要更新id=1的行,這是會被阻塞,因為id=1的行鎖需要等到t5時刻session1 commit后才會被釋放。
    對程序的影響
    在編寫程序時,程序員應(yīng)當(dāng)盡量將需要請求行鎖的代碼放到離commit更近的地方。

死鎖預(yù)防措施

  • 我們知道死鎖發(fā)生的條件

    1. 多個資源互斥訪問
    2. 資源被獲取后不可搶占
    3. 多個線程循環(huán)等待
  • 在數(shù)據(jù)庫行級鎖場景下,這些條件都會被滿足,因此對于行級鎖的請求肯定會造成死鎖。那我們應(yīng)當(dāng)如何解決死鎖呢,有如下兩種辦法:

    1. 死鎖檢測
      著名的死鎖檢測方法就是銀行家算法,不知道的小伙伴可以查一下。但這有個非常大的缺點(diǎn),每次死鎖檢測的時間復(fù)雜度為O(N),因此如果有1000個線程要執(zhí)行加鎖操作時就會帶來100萬級別的時間復(fù)雜度開銷。

    2. 控制并發(fā)度
      很好理解,線程數(shù)越少死鎖發(fā)生的概率越小。可以通過控制統(tǒng)一時刻訪問同一行的請求數(shù)量來控制并發(fā)度以減少死鎖發(fā)生的概率。另一種方式就是將數(shù)據(jù)分散,比如數(shù)據(jù)庫中原來有一行數(shù)據(jù)記錄用戶在銀行的存款數(shù)額,現(xiàn)在將其拆分成10行,10行數(shù)額的相加就是這個用戶的存款數(shù),當(dāng)一個請求要修改該用戶的存款數(shù)額的時候,就隨機(jī)從10行中選一行進(jìn)行操作,這樣就將并發(fā)度減少為了1/10。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容