5分鐘看懂髒讀、不可重複讀和幻讀

講事務隔離機制的文章看了不少,覺得有些文章寫的確實難以理解,造成不少理解偏差。這篇文章以大白話來解釋。

下面舉例說明髒讀,不可重複讀,幻讀:(以A君買STEAM的遊戲的例子來說)

髒讀

在Read Uncommitted級別下存在,使用Read Committed級別以解決

大白話解釋:事務A未提交時,事務B就讀了事務A未提交的數據

舉例:A君準備買了一款新遊戲,填寫了購買申請,但是猶豫再三,到底要不要提交,這時候A君的老婆通過select訂單詳情居然發現了A君的申請,頓時大怒。但實際上A君後來刪除了申請,雖然沒買遊戲,但是A君老婆還是認爲已經有了訂單,爲此吵了一大架。

不可重複讀

在Read Committed級別下存在,使用Repeatable Read級別以解決

 大白話解釋:事務B一直在關注一條數據,事務A去修改這條數據,修改後立刻提交,但是在修改期間,事務B一直未提交,多次查詢該條數據,但是發現結果不一樣,不知道該相信哪一個結果。

舉例:

       這一天A君老婆心情不錯,允許A君可以購買50元以下的遊戲,A君老婆一直通過後臺來監控是否超標。於是A君下單,並提交了訂單,但是價格選高了,是總價100元的遊戲,此時A君老婆發現了這條100元的訂單,覺得很生氣,但是此時並沒有關閉查詢界面(事務未提交)。此時A君也意識到選錯了,修改了訂單並提交。此時A君老婆繼續查詢訂單,發現價格變成了50元,這下不知道該相信誰了,覺得其中有詐,雖然A君沒有超標並買了遊戲,但還是被老婆懷疑了。

幻讀 

在Repeatable Read級別下存在,使用Serializable級別以解決 (如果是Mysql,則得益於MVCC機制,在Repeatable Read下就可解決)

 大白話解釋:事務B先按條件查詢了條件S下的數據數量(B不提交),此時事務A向表中多次插入和刪除符合條件S的數據,每次修改後馬上提交,事務B多次以條件S檢索數據數量,但是發現數量不一樣了,不知道該相信哪一個結果。

舉例:

        A君老婆允許A君再購買2款遊戲,通過訂單系統一直查詢A君的遊戲數量,A君提交了2款遊戲的訂單,但是網絡延遲導致多提交了2款遊戲的訂單,A君馬上又刪除了多餘的訂單。在此期間A君老婆通過訂單系統先看到了2條訂單,之後查詢又出現了2條訂單,再查又發現多出的2條訂單不見了,不知道A君到底買了幾款遊戲,覺得A君老是這麼不靠譜,和A君大吵了一架。

總結

  • 以上3種情況的發生,均是通過某個一直未提交的事務發現的。
  • 髒讀、不可重複讀,是在單行數據產生,幻讀在多行數據中產生。
  • 幻讀中出現的異常數據稱爲“幻影行”
  • 不可重複讀和幻讀發生的場景很像:均是一個事務在不停提交,另一個事務一直不提交。
  • 不可重複讀和幻讀容易搞混,可以這麼理解:不可重複讀是一條數據出現了“幻影結果”,幻讀是一個表中出現了幻影行。
  • 由於不可重複讀和幻讀產生情況很像,所以Mysql的MVCC機制就能一次都把他們解決了。(和SVN原理類似,具體還在學習)

不知道是否能夠描述準確,歡迎留言交流。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章