溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點(diǎn)擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

MySQL中怎么重復(fù)讀間隙鎖

發(fā)布時間:2021-08-02 15:53:31 來源:億速云 閱讀:118 作者:Leah 欄目:數(shù)據(jù)庫

MySQL中怎么重復(fù)讀間隙鎖,很多新手對此不是很清楚,為了幫助大家解決這個難題,下面小編將為大家詳細(xì)講解,有這方面需求的人可以來學(xué)習(xí)下,希望你能有所收獲。

間隙鎖(Gap  Lock)是Innodb在可重復(fù)讀提交下為了解決幻讀問題時引入的鎖機(jī)制,(下面的所有案例沒有特意強(qiáng)調(diào)都使用可重復(fù)讀隔離級別)幻讀的問題存在是因?yàn)樾略龌蛘吒虏僮?,這時如果進(jìn)行范圍查詢的時候(加鎖查詢),會出現(xiàn)不一致的問題,這時使用不同的行鎖已經(jīng)沒有辦法滿足要求,需要對一定范圍內(nèi)的數(shù)據(jù)進(jìn)行加鎖,間隙鎖就是解決這類問題的。在可重復(fù)讀隔離級別下,數(shù)據(jù)庫是通過行鎖和間隙鎖共同組成的(next-key  lock),來實(shí)現(xiàn)的。

加鎖規(guī)則有以下特性,我們會在后面的案例中逐一解釋:

  • 1.加鎖的基本單位是(next-key lock),他是前開后閉原則

  • 2.插敘過程中訪問的對象會增加鎖

  • 3.索引上的等值查詢--給唯一索引加鎖的時候,next-key lock升級為行鎖

  • 4.索引上的等值查詢--向右遍歷時最后一個值不滿足查詢需求時,next-key lock 退化為間隙鎖

  • 5.唯一索引上的范圍查詢會訪問到不滿足條件的第一個值為止

案例數(shù)據(jù)

MySQL中怎么重復(fù)讀間隙鎖

以上數(shù)據(jù)為了解決幻讀問題,更新的時候不只是對上述的五條數(shù)據(jù)增加行鎖,還對于中間的取值范圍增加了6間隙鎖,(-∞,5](5,10](10,15](15,20](20,25](25,+supernum]  (其中supernum是數(shù)據(jù)庫維護(hù)的最大的值。為了保證間隙鎖都是左開右閉原則。)

案例一:間隙鎖簡單案例

MySQL中怎么重復(fù)讀間隙鎖

當(dāng)有如下事務(wù)A和事務(wù)B時,事務(wù)A會對數(shù)據(jù)庫表增加(10,15]這個區(qū)間鎖,這時insert id = 12  的數(shù)據(jù)的時候就會因?yàn)閰^(qū)間鎖(10,15]而被鎖住無法執(zhí)行。

案例二: 間隙鎖死鎖問題

MySQL中怎么重復(fù)讀間隙鎖

不同于寫鎖相互之間是互斥的原則,間隙鎖之間不是互斥的,如果一個事務(wù)A獲取到了(5,10]之間的間隙鎖,另一個事務(wù)B也可以獲取到(5,10]之間的間隙鎖。這時就可能會發(fā)生死鎖問題,如下案例。

事務(wù)A獲取到(5,10]之間的間隙鎖不允許其他的DDL操作,在事務(wù)提交,間隙鎖釋放之前,事務(wù)B也獲取到了間隙鎖(5,10],這時兩個事務(wù)就處于死鎖狀態(tài)

案例三: 等值查詢—唯一索引

MySQL中怎么重復(fù)讀間隙鎖

1.加鎖的范圍是(5,10]的范圍鎖

2.由于數(shù)據(jù)是等值查詢,并且表中最后數(shù)據(jù)id = 10 不滿足id= 7的查詢要求,故id=10 的行級鎖退化為間隙鎖,(5,10)

3.所以事務(wù)B中id=8會被鎖住,而id=10的時候不會被鎖住

案例四: 等值查詢—普通索引

MySQL中怎么重復(fù)讀間隙鎖

1.加鎖的范圍是(0,5],(5,10]的范圍鎖

2.由于c是普通索引,根據(jù)原則4,搜索到5后繼續(xù)向后遍歷直到搜索到10才放棄,故加鎖范圍為(5,10]

3.由于查詢是等值查詢,并且最后一個值不滿足查詢要求,故間隙鎖退化為(5,10)

4.因?yàn)榧渔i是對普通索引c加鎖,而且因?yàn)樗饕采w,沒有對主鍵進(jìn)行加鎖,所以事務(wù)B執(zhí)行正常

5.因?yàn)榧渔i范圍(5,10)故事務(wù)C執(zhí)行阻塞

6.需要注意的是,lock in share mode 因?yàn)楦采w索引故沒有鎖主鍵索引,如果使用for update  程序會覺得之后會執(zhí)行更新操作故會將主鍵索引一同鎖住

案例五: 范圍查詢—唯一索引

MySQL中怎么重復(fù)讀間隙鎖

next-key lock 增加范圍鎖(5,10]

根據(jù)原則5,唯一索引的范圍查詢會到第一個不符合的值位置,故增加(10,15]

因?yàn)榈戎挡樵冇衖d =10 根據(jù)原則3間隙鎖升級為行鎖,故剩余鎖[10,15]

因?yàn)椴樵儾⒉皇堑戎挡樵?,故[10,15]不會退化成[10,15)

故事務(wù)B(13,13,13)阻塞,事務(wù)C阻塞

案例六: 范圍查詢—普通索引

MySQL中怎么重復(fù)讀間隙鎖

next-key lock 增加范圍鎖(5,10],(10,15]

因?yàn)閏是非唯一索引,故(5,10]不會退化為10

因?yàn)椴樵儾⒉皇堑戎挡樵?,故[10,15]不會退化成[10,15)

所以事務(wù)B和事務(wù)C全部堵塞

案例七: 普通索引-等值問題

上面的數(shù)據(jù)增加一行(30,10,30),這樣在數(shù)據(jù)庫中存在的c=10的就有兩條記錄

MySQL中怎么重復(fù)讀間隙鎖
MySQL中怎么重復(fù)讀間隙鎖

next-key lock 增加范圍鎖(5,10],(10,15]

因?yàn)槭堑戎挡樵児释嘶癁?5,10],(10,15),故事務(wù)B阻塞,事務(wù)C執(zhí)行成功

加鎖的范圍如下圖

案例八: 普通索引-等值Limit問題

MySQL中怎么重復(fù)讀間隙鎖

看完上述內(nèi)容是否對您有幫助呢?如果還想對相關(guān)知識有進(jìn)一步的了解或閱讀更多相關(guān)文章,請關(guān)注億速云行業(yè)資訊頻道,感謝您對億速云的支持。

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI