十年網(wǎng)站開發(fā)經(jīng)驗 + 多家企業(yè)客戶 + 靠譜的建站團隊
量身定制 + 運營維護+專業(yè)推廣+無憂售后,網(wǎng)站問題一站解決
據(jù)此,很多人判斷說RR隔離級別下“不存在”幻讀。但果真如此嗎?--- 出現(xiàn)上面的試驗結果,是因為在RR隔離級別事務下,Mysql會對前一次select的結果快照。

成都創(chuàng)新互聯(lián)公司長期為超過千家客戶提供的網(wǎng)站建設服務,團隊從業(yè)經(jīng)驗10年,關注不同地域、不同群體,并針對不同對象提供差異化的產(chǎn)品和服務;打造開放共贏平臺,與合作伙伴共同營造健康的互聯(lián)網(wǎng)生態(tài)環(huán)境。為鷹手營子企業(yè)提供專業(yè)的成都做網(wǎng)站、網(wǎng)站建設,鷹手營子網(wǎng)站改版等技術服務。擁有十多年豐富建站經(jīng)驗和眾多成功案例,為您定制開發(fā)。
可以看到事務a已提交的新數(shù)據(jù)被事務b使用update語句更新了,并且通過普通的select語句給查詢出來了,很顯然,出現(xiàn)了幻讀 。所以說InnoDB的RR隔離級別沒有或者解決了幻讀問題都不太準確。應該說它并沒有完全解決幻讀的問題。
先明確一下,for update語法就是當前讀,也就是查詢當前已經(jīng)提交的數(shù)據(jù),并且是帶悲觀鎖的。沒有for update就是快照讀,也就是根據(jù)readView讀取的undolog中的數(shù)據(jù)。 如果按照以上猜想,那么整個執(zhí)行結果就違背了 可重復讀 的隔離級別了。
MySQL InnoDB 存儲引擎的默認支持的隔離級別是 REPEATABLE-READ(可重讀) 。
總結:從上往下依次降低,隔離級別的強度依次增強。下面我們有一個圖來進行解釋:讀取未提交:不可重復讀,幻讀問題。 解決問問題:沒有使用事物的時候數(shù)據(jù)不一致的問題,就是做到知行的sql一起成功,一起回滾。
1、因此,為了解決幻讀問題,InnoDB只好引入新的鎖,也就是間隙鎖(Gap Lock)。間隙鎖和行鎖合稱 next-key lock , 每個next-key lock是前開后閉區(qū)間 。
2、回到正題,之前提到一般情況下MySQL的InnoDB引擎在可重復讀的情況下是沒法保證不出現(xiàn)幻讀的,但實際情況是MySQL可以通過加鎖來防止幻讀的出現(xiàn),這種鎖定通過Next-key機制來實現(xiàn),是屬于記錄鎖和間隙鎖(Gap鎖)的結合。
3、MySQL在解決臟讀、不可重復的讀時候,使用了MVCC一致性視圖,同時配合行鎖來解決。
1、其他:MySQL InnoDB 引擎 RR 隔離級別是否解決了幻讀引用一個 github 上面的評論 地址:Mysqlguan 方給出的幻讀解釋是:只要在一個事務中,第二次select多出了row就算幻讀。
2、幻讀指的是一個事務在前后兩次查詢同一個范圍的時候,后一次查詢看到了前一次查詢沒有看到的行。首先快照讀是不存在幻讀的,只有當前讀(實時讀)才存在幻讀的問題。
3、首先需要明確的就是“幻讀”概念: 隔離級別是可重復讀,在一個事務中前后兩次查詢,查到了其他事務insert進來的數(shù)據(jù)。 強調(diào)的是讀取到了其他事務插入進來的數(shù)據(jù)。
1、MySQL在解決臟讀、不可重復的讀時候,使用了MVCC一致性視圖,同時配合行鎖來解決。
2、此外要提的一點是,MySql的REPEATABLE READ與Oracle的不同,不但解決了不可重復讀問題,還解決的“幻讀”問題。
3、可重復讀隔離級別下,事務在啟動的時候就“拍了個整個庫的快照”。如果一個庫有100G,那么我啟動一個事務,MySQL就要拷100G的數(shù)據(jù)出來,這個過程得多慢啊。但是平時事務執(zhí)行起來卻是非??斓?。
其他:MySQL InnoDB 引擎 RR 隔離級別是否解決了幻讀引用一個 github 上面的評論 地址:Mysqlguan 方給出的幻讀解釋是:只要在一個事務中,第二次select多出了row就算幻讀。
解決mysql臟讀的方法:mysql數(shù)據(jù)庫定義了四種隔離級別:serializable:可避免臟讀、不可重復讀、虛讀情況的發(fā)生。repeatable read:可以避免臟讀、不可重復讀情況的發(fā)生。read committed:可以避免臟讀情況發(fā)生。
以mysql來說,可能出現(xiàn)臟讀、不可重復讀以及幻讀,mysql默認設置是可重復讀,即一次事務中不會讀取到不同的數(shù)據(jù)。
MySQL InnoDB事務隔離級別臟讀、可重復讀、幻讀MySQL InnoDB事務的隔離級別有四級,默認是“可重復讀”(REPEATABLE READ)?!?1).未提交讀(READUNCOMMITTED)。
首先快照讀是不存在幻讀的,只有當前讀(實時讀)才存在幻讀的問題。幻讀有什么問題?select ...for update語句就是將相應的數(shù)據(jù)行鎖住,但是如果存在幻讀,就把for update的語義破壞了。
對于[ UPDATE ]語句,如果某行已被鎖定,則 InnoDB 執(zhí)行“半一致”讀取,將最新提交版本的數(shù)據(jù)返回給MySQL,以便MySQL可以確定該行是否符合 WHERE 條件。
針對這個情況,我們要解決幻讀的問題,那么就要求針對所有被掃描的記錄行以及還不存在的d=5的記錄行都給鎖住。 至此,當前查詢結果完全滿足 可重復讀 的隔離級別。
所以說InnoDB的RR隔離級別沒有或者解決了幻讀問題都不太準確。應該說它并沒有完全解決幻讀的問題。如果在同一個事務里面,只是總是執(zhí)行普通的select快照讀,是不會產(chǎn)生幻讀的。
回到正題,之前提到一般情況下MySQL的InnoDB引擎在可重復讀的情況下是沒法保證不出現(xiàn)幻讀的,但實際情況是MySQL可以通過加鎖來防止幻讀的出現(xiàn),這種鎖定通過Next-key機制來實現(xiàn),是屬于記錄鎖和間隙鎖(Gap鎖)的結合。