1. 程式人生 > >髒讀、不可重複讀、幻讀的簡單理解

髒讀、不可重複讀、幻讀的簡單理解

首先看看“髒讀”,看到“髒”這個字,我就想到了噁心、骯髒。資料怎麼可能髒呢?其實也就是我們經常說的“垃圾資料”了。比如說,有兩個事務,它們在併發執行(也就是競爭)。看看以下這個表格,您一定會明白我在說什麼:

餘額應該為 1100 元才對!請看 T6 時間點,事務 A 此時查詢餘額為 900 元,這個資料就是髒資料,它是事務 A 造成的,明顯事務沒有進行隔離,滲過來了,亂套了。

所以髒讀這件事情是非常要不得的,一定要解決掉!讓事務之間隔離起來才是硬道理。

不可重複讀又怎麼解釋呢?還是用類似的例子來說明:

 

不可重複讀是指A事務讀取了B事務已經提交的更改資料。假如A在取款事務的過程中,B往該賬戶轉賬100,A兩次讀取的餘額發生不一致。

幻讀。A事務讀取B事務提交的新增資料,會引發幻讀問題。幻讀一般發生在計算統計資料的事務中,例如銀行系統在同一個事務中兩次統計存款賬戶的總金額,在兩次統計中,剛好新增了一個存款賬戶,存入了100,這時候兩次統計的總金額不一致。

銀行工作人員,每次統計總存款,都看到不一樣的結果。不過這也確實也挺正常的,總存款增多了,肯定是這個時候有人在存錢。但是如果銀行系統真的這樣設計,那算是玩完了。這同樣也是事務沒有隔離所造成的,但對於大多數應用系統而言,這似乎也是正常的,可以理解,也是允許的。銀行裡那些噁心的那些系統,要求非常嚴密,統計的時候,甚至會將所有的其他操作給隔離開,這種隔離級別就算非常高了(估計要到 SERIALIZABLE 級別了)。

注意:不可重複讀和幻讀的區別是:前者是指讀到了已經提交的事務的更改資料(修改或刪除),後者是指讀到了其他已經提交事務的新增資料。對於這兩種問題解決採用不同的辦法,防止讀到更改資料,只需對操作的資料新增行級鎖,防止操作中的資料發生變化;二防止讀到新增資料,往往需要新增表級鎖,將整張表鎖定,防止新增資料(oracle採用多版本資料的方式實現)。 

第一類丟失更新,A事務撤銷時,把已經提交的B事務的更新資料覆蓋了。這種錯誤可能造成很嚴重的問題,通過下面的賬戶取款轉賬就可以看出來:

但是,在當前的四種任意隔離級別中,都不會發生該情況,不然絕對亂套,我都沒提交事務只是撤銷,就把別人的給覆蓋了,這也太恐怖了。

第二類丟失更新,B事務覆蓋A事務已經提交的資料,造成A事務所做操作丟失

歸納一下,以上提到了事務併發所引起的跟讀取資料有關的問題,各用一句話來描述一下:

  1.髒讀:事務 A 讀取了事務 B 未提交的資料,並在這個基礎上又做了其他操作。

  2.不可重複讀:事務 A 讀取了事務 B 已提交的更改資料。

  3.幻讀:事務 A 讀取了事務 B 已提交的新增資料。

第一條是堅決抵制的,後兩條在大多數情況下可不作考慮。