Mysql中的innoDB如何解決幻讀
1.Mysql的事務(wù)隔離級別
這四種隔離級別,當(dāng)存在多個事務(wù)并發(fā)沖突的時候,可能會出現(xiàn)臟讀,不可重復(fù)讀,幻讀的一些問題,而innoDB
在可重復(fù)讀隔離級別模式下解決了幻讀的一個問題,
2. 什么是幻讀
幻讀是指在同一個事務(wù)中,前后兩次查詢相同范圍的時候得到的結(jié)果不一致
如圖,第一個事務(wù)里面,我們執(zhí)行一個范圍查詢,這個時候滿足條件的數(shù)據(jù)只有一條,而在第二個事務(wù)里面,它插入一行數(shù)據(jù)并且進行了提交,接著第一個事務(wù)再去查詢的時候,得到的結(jié)果比第一次查詢的結(jié)果多出來一條數(shù)據(jù),注意第一個事務(wù)的第一次和第二次查詢,都在同一個事物里面,所以,幻讀會帶來數(shù)據(jù)一致性的問題
3. InnoDB如何解決幻讀的問題
InnoDB引入間隙鎖
和next-key lock
機制去解決幻讀問題
假如現(xiàn)在存在這樣一個B+Tree的索引結(jié)構(gòu),這個結(jié)構(gòu)有4個索引元素,分別是1,4,7,10 當(dāng)我們通過主鍵索引查詢一條記錄,并且對這條記錄通過for update
加鎖的時候
這個時候會產(chǎn)生一個記錄鎖,也就是行鎖,鎖定id=1
這個索引
被鎖定的記錄在鎖釋放之前,其他事務(wù)無法對這一條記錄做任何操作的,前面我們所過對幻讀的定義,幻讀是指在同一個事務(wù)中,前后兩次查詢相同范圍的時候得到的結(jié)果不一致,注意這里敲掉的是范圍查詢,也就是說要解決幻讀的問題,必須保證一個點
就是如果一個事務(wù)通過這樣一條語句進行鎖定的時候,另外一個事務(wù)再執(zhí)行
這樣一條insert語句需要被阻塞,直到前面獲得所的事務(wù)被釋放,所以在innonDB設(shè)計一種間隙鎖
,它的主要功能是鎖定一定范圍內(nèi)的索引記錄
當(dāng)對查詢范圍id > 4 and id < 7
這個范圍加鎖的時候,會針對B+數(shù)中(4,7)這個開區(qū)間的范圍加間隙鎖
,意味著在這種情況下其他事務(wù)對這個區(qū)間的數(shù)據(jù)進行插入更新刪除都會被鎖住,但是還有另外一種情況,比如像這樣
這條查詢語句針對id > 4
這個條件加鎖,那么它需要鎖定多個索引區(qū)間,所以這個情況下InnoDB引入一個叫next-key lock
機制,next-key lock
相當(dāng)于間隙鎖和記錄鎖的合集,記錄鎖鎖定存在記錄的行,間隙鎖鎖住的是記錄行之間的間隙,而next-key lock
鎖住的是兩者的和
每個數(shù)據(jù)行非唯一的索引列,都會存在一把next-key lock
,當(dāng)某個事務(wù)持有這一行數(shù)據(jù)的next-key lock
的時候,會鎖住一段在左開右閉區(qū)間的數(shù)據(jù),因此當(dāng)通過id > 4
這樣一個范圍加鎖的時候,InnoDB會去加一個next-key lock
鎖,鎖定的區(qū)間范圍是(4,7 ](7,10 ](10,+?? ]。間隙鎖
和next-key lock
的區(qū)別是在加鎖的范圍,間隙鎖
鎖定的是兩個索引之間的間隙,而next-key lock
會鎖定多個索引區(qū)間,它包含記錄鎖
和間隙鎖
當(dāng)我們使用范圍查詢不僅僅命中Record記錄,還包含了Gap間隙的時候,在這種情況下使用的就是臨鍵鎖,也就是next-key lock
它是Mysql里面默認的行鎖算法
4. 總結(jié)
雖然InnoDB里面通過間隙鎖
方式解決了幻讀的問題但是加鎖之后一定會影響到并發(fā)性能,因此對與性能較高的一些業(yè)務(wù)場景,我們可以把隔離級別設(shè)置不可重復(fù),那么這個級別不存在間隙鎖,也不存在性能的影響
相關(guān)文章
在IntelliJ IDEA中使用Java連接MySQL數(shù)據(jù)庫的方法詳解
這篇文章主要介紹了在IntelliJ IDEA中使用Java連接MySQL數(shù)據(jù)庫的方法詳解,本文通過圖文并茂的形式給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2020-10-10MySQL 數(shù)據(jù)庫如何解決高并發(fā)問題
這篇文章主要介紹了MySQL 如何處理高并發(fā),幫助大家更好的優(yōu)化MySQL數(shù)據(jù)庫,感興趣的朋友可以了解下2020-09-09Idea連接MySQL數(shù)據(jù)庫出現(xiàn)中文亂碼的問題
這篇文章主要介紹了Idea連接MySQL數(shù)據(jù)庫出現(xiàn)中文亂碼的問題,本文給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2021-04-04Win10安裝MySQL5.7.18winX64 啟動服務(wù)器失敗并且沒有錯誤提示
這篇文章主要介紹了Win10安裝MySQL5.7.18winX64 啟動服務(wù)器失敗并且沒有錯誤提示,需要的朋友可以參考下2017-06-06mysql 5.7.16 安裝配置方法圖文教程(ubuntu 16.04)
這篇文章主要為大家分享了ubuntu 16.04下mysql 5.7.16 安裝配置方法圖文教程,具有一定的參考價值,感興趣的小伙伴們可以參考一下2017-01-01mysql之?dāng)?shù)據(jù)庫常用腳本總結(jié)
這篇文章主要介紹了mysql之?dāng)?shù)據(jù)庫常用腳本總結(jié),具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2023-03-03