事物系統的幾種異常場景

KunlunDB發表於2022-01-20
  • 背景


筆者最近在回顧多版本併發控制(MVCC),這裡對相關內容做個小總結,首先就從隔離級別說起。

  • 為什麼要討論隔離,場景是什麼?


首先,作為事務系統,如果單位時間內,只有一個事務在執行,則談不上隔離。

可是實際上,真正用於實際生產的事務系統,單位時間內都是有多個事務同時的在對資源進行著讀寫。

那麼就必定會存在對同一個資源的併發讀寫問題,如果不加以控制則一定會出錯。

因此這裡討論問題的場景就是多事務併發環境下得資料處理場景。

  • 隔離能解決什麼問題?為什麼要對隔離進行分級?


什麼樣的事務系統是合理的,正確的, 或者說能夠準確地對現實世界的邏輯進行抽象的?滿足 ACID 特性。滿足 C 就要實現 I,因此隔離的目的是為了滿足 C。

然而要回答為何要對隔離進行分級,我們得先從不滿足 C 的異常場景得拆解來入手分析下。

  • 事務系統的幾種異常場景


1、 Lost Update 更新丟失

何為更新丟失?兩個併發的事務T1、T2,不加任何鎖的對對同一塊資源進行寫操作。T1 更改的結果被 T2 事務篡改,這就是更新丟失。 直白點就是沒有任何隔離手段,純併發。這種場景,不能出現在任何合理的應用系統中,屬於基礎重大錯誤。

2、 Dirty Read 髒讀

髒讀的定義,就是讀取到了髒資料。這裡首先明確什麼是髒資料。

在事務系統中,髒資料是指未提交的資料,中間狀態的資料。那麼讀取到了事務沒有提交的資料,就是讀取到了髒資料,稱為髒讀。 可以用下面的圖來表示:

事物系統的幾種異常場景

圖片來源於網路

有兩個事務 T1 T2 同時存在,T1 更改了 a 的值,在沒提交的時候,T2 讀取到了 a 被 T1 更改後的值。如果此時,T1 回滾了,那麼 T2 讀取到的 a 的值,就是一個不被認為存在的值,或者是讀取到了事務的中間狀態,這就是髒讀。

我們可以簡單的用加鎖的方法來理解即:這裡所有事務在對臨界資源的訪問上,只加了讀鎖。這意味著,其他的事務可以在任意時刻讀取未提交的資料(因為讀鎖是相容的),但是不能寫已經被修改的資料(因為讀鎖和寫鎖不相容)。因此在髒讀的場景下,一般預設是認為,更新丟失的問題已經得到了解決。


3、 Un-repeatable Read / Read skew 不可重複度 / 讀偏序

不可重複讀的指的場景是,事務T1讀取到的資料因其他事務T2的修改並提交後,當T1再次讀取時,出現了不同的結果。我們這裡首先看下, 不可重複讀和髒讀的區別是:不可重複讀,讀取到的所有的結果,都是已經提交的資料,髒資料看不到了。可以用下面的圖來表示下:

事物系統的幾種異常場景

圖片來源於網


通過上圖我們簡單理解,得以實現不可重複度與髒讀區別的,是在 T2 事務準備寫資料的時候,實現了這裡的讀鎖向寫鎖的升級,使得 T1 無法讀取 T2 事務提交前的資料值,但是當 T2 完成釋放了所有的鎖後,T1 再次讀取資料時,已經是被修改後的版本。

4、 Phantom Read 幻讀

幻讀指的是,T1 事務在執行過程中的不同時間點,以相同的謂詞條件獲得的結果集不同,這裡只限定為多出了資料,而不是資料不同。這裡我們需要明確的是, 幻讀相對於上面提到的不可重複度的區別是:幻讀場景下,已經沒有不可重複讀的問題,即兩次查詢相同主鍵的值相同,只是多出了部分記錄 (為什麼不是少了資料?)。 可以用下面的圖來表示:

事物系統的幾種異常場景

圖片來源於網


我們可以簡單的理解為,事務 T1 在對所要操作的資源上, 只讀的資料加讀鎖,要修改的資料加寫鎖,並且都是事務提交後釋放。因此其他的事務無法對相同的資源進行修改,因此在幻讀的場景下,不可重複度的情況不會發生。但是 T1 卻無法對新產生的資料行加鎖,因此在這裡體現了幻讀的與不可重複度的區別即相同謂詞的結果集不同,一般指後一次的結果集是前一次結果集的超集。

  • 總結


從上面的分析拆解,以及從加鎖的角度來理解這幾個異常場景,可以發現一個 遞進關係:在解決了上一個問題時,又發現了下一個新問題。因此才引出了,根據這幾個異常場景來定義的不同的有遞進關係的隔離級別的概念。

在下篇章< 事務系統的隔離級別> 的分析中 ,我們依舊可以 發現, 每個隔離級別,解決一個層次的問題。敬請期待~

-END-


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/70011764/viewspace-2853162/,如需轉載,請註明出處,否則將追究法律責任。

相關文章