mysql Innodb在RR級別如何避免幻讀


  • 什么是幻讀

    事務不是獨立執行時發生的一種現象,例如第一個事務對一個表中的數據進行了修改,這種修改涉及到表中的全部數據行。 同時,第二個事務也修改這個表中的數據,這種修改是向表中插入一行新數據。那么,以后就會發生操作第一個事務的用戶發現表中還有沒有修改的數據行,就好象 發生了幻覺一樣。

  • mysql如何實現避免幻讀

    • 在快照讀讀情況下,mysql通過mvcc來避免幻讀。
    • 在當前讀讀情況下,mysql通過next-key來避免幻讀
  • 什么是mvcc

    mvcc全稱是multi version concurrent control(多版本並發控制)。mysql把每個操作都定義成一個事務,每開啟一個事務,系統的事務版本號自動遞增。每行記錄都有兩個隱藏列:創建版本號和刪除版本號

    • select:事務每次只能讀到創建版本號小於等於此次系統版本號的記錄,同時行的刪除版本號不存在或者大於當前事務的版本號。

    • update:插入一條新記錄,並把當前系統版本號作為行記錄的版本號,同時保存當前系統版本號到原有的行作為刪除版本號。

    • delete:把當前系統版本號作為行記錄的刪除版本號

    • insert:把當前系統版本號作為行記錄的版本號

  • 什么是next-key鎖

    可以簡單的理解為X鎖+GAP鎖 //行鎖 +間隙鎖

  • 什么是快照讀和當前讀

    • 快照讀:簡單的select操作,屬於快照讀,不加鎖。(當然,也有例外,下面會分析)

      • select * from table where ?;
    • 當前讀:特殊的讀操作,插入/更新/刪除操作,屬於當前讀,需要加鎖。

      • select * from table where ? lock in share mode;
      • select * from table where ? for update;
      • insert into table values (…);
      • update table set ? where ?;
      • delete from table where ?;

Mysql官方給出的幻讀解釋是:只要在一個事務中,第二次select多出了row就算幻讀。
a事務先select,b事務insert確實會加一個gap鎖,但是如果b事務commit,這個gap鎖就會釋放(釋放后a事務可以隨意dml操作),a事務再select出來的結果在MVCC下還和第一次select一樣,接着a事務不加條件地update,這個update會作用在所有行上(包括b事務新加的),a事務再次select就會出現b事務中的新行,並且這個新行已經被update修改了,實測在RR級別下確實如此。

如果這樣理解的話,Mysql的RR級別確實防不住幻讀

有道友回復 地址

在快照讀讀情況下,mysql通過mvcc來避免幻讀。
在當前讀讀情況下,mysql通過next-key來避免幻讀。
select * from t where a=1;屬於快照讀
select * from t where a=1 lock in share mode;屬於當前讀

不能把快照讀和當前讀得到的結果不一樣這種情況認為是幻讀,這是兩種不同的使用方式。所以我認為mysql的rr級別是解決了幻讀的。

先說結論,MySQL 存儲引擎 InnoDB 隔離級別 RR 解決了幻讀問題。

不能把快照讀和當前讀得到的結果不一樣這種情況認為是幻讀,這是兩種不同的使用方式。所以認為 MySQL 的 RR 級別是解決了幻讀的。next-key 固然很好的解決了幻讀問題,但是還是遵循一般的定律,隔離級別越高,並發越低。

 
 


鏈接:https://www.jianshu.com/p/2953c64761aa


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM