天天看點

事務(髒讀,不可重複讀,虛讀)

髒讀 dirty reads:當事務讀取還未被送出的資料時,就會發生這種事件。舉例來說:Transaction 1 修改了一行資料,然後 Transaction 2 在 Transaction 1 還未送出修改操作之前讀取了被修改的行。如果 Transaction 1 復原了修改操作,那麼 Transaction 2 讀取的資料就可以看作是從未存在過的。

不可重複的讀 non-repeatable reads:當事務兩次讀取同一行資料,但每次得到的資料都不一樣時,就會發生這種事件。舉例來說:Transaction 1 讀取一行資料,然後 Transaction 2 修改或删除該行并送出修改操作。當 Transaction 1 試圖重新讀取該行時,它就會得到不同的資料值(如果該行被更新)或發現該行不再存在(如果該行被删除)。

虛讀 phantom read:如果符合搜尋條件的一行資料在後面的讀取操作中出現,但該行資料卻不屬于最初的資料,就會發生這種事件。舉例來說:Transaction 1 讀取滿足某種搜尋條件的一些行,然後 Transaction 2 插入了符合 Transaction 1 的搜尋條件的一個新行。如果 Transaction 1 重新執行産生原來那些行的查詢,就會得到不同的行。

事務場景是這樣的:

對于同一個銀行帳戶A内有200元,甲進行提款操作100元,乙進行轉帳操作100元到B帳戶。如果事務沒有進行隔離可能會并發如下問題:

1、第一類丢失更新:首先甲提款時帳戶内有200元,同時乙轉帳也是200元,然後甲乙同時操作,甲操作成功取走100元,乙操作失敗復原,帳戶内最終為200元,這樣甲的操作被覆寫掉了,銀行損失100元。

2、髒讀:甲取款100元未送出,乙進行轉帳查到帳戶内剩有100元,這是甲放棄操作復原,乙正常操作送出,帳戶内最終為0元,乙讀取了甲的髒資料,客戶損失100元。

3、虛讀:和髒讀類似,是針對于插入操作過程中的讀取問題,如丙存款100元未送出,這時銀行做報表進行統計查詢帳戶為200元,然後丙送出了,這時銀行再統計發現帳戶為300元了,無法判斷到底以哪個為準?

大家好像覺得統計這個東西肯定是時時更新的,這種情況很正常;但是如果統計是在一個事務中的時候就不正常了,比如我們的一個統計應用需要将統計結果分别輸出到電腦螢幕和遠端網絡某台計算機的磁盤檔案中,為了

提高性能和使用者響應我們分成2個線程,這時先完成的和後完成的統計資料就可能不一緻,我們就不知道以哪個為準了。

4、不可重複讀:甲乙同時開始都查到帳戶内為200元,甲先開始取款100元送出,這時乙在準備最後更新的時候又進行了一次查詢,發現結果是100元,這時乙就會很困惑,不知道該将帳戶改為100還是0。

和髒讀的差別是,髒讀是讀取前一事務未送出的髒資料,不可重複讀是重新讀取了前一事務已送出的資料。

5、第二類丢失更新:是不可重複讀的一種特例,如上,乙不做第二次查詢而是直接操作完成,帳戶内最終為100元,甲的操作被覆寫掉了,銀行損失100元。感覺和第一類丢失更新類似。

在多個事務并發做資料庫操作的時候,如果沒有有效的避免機制,就會出現種種問題。大體上有三種問題,歸結如下:

1、丢失更新

如果兩個事務都要更新資料庫一個字段X,x=100

事務A 事務B

讀取X=100

讀取X=100

寫入x=X+100

寫入x=X+200

事務結束x=200

事務結束x=300

最後x==300

這種情況事務A的更新就被覆寫掉了、丢失了。

丢失更新說明事務進行資料庫寫操作的時候可能會出現的問題。

2、不可重複讀

一個事務在自己沒有更新資料庫資料的情況,同一個查詢操作執行兩次或多次的結果應該是一緻的;如果不一緻,就說明為不可重複讀。

還是用上面的例子

事務A 事務B

讀取X=100

讀取X=100

讀取X=100

寫入x=X+100

讀取X=200

事務結束x=200

事務結束x=200

這種情況事務A多次讀取x的結果出現了不一緻,即為不可重複讀。

再有一情況就是幻影

事務A讀的時候讀出了15條記錄,事務B在事務A執行的過程中删除(增加)了1條,事務A再讀的時候就變成了14(16)條,這種情況就叫做幻影讀。

不可重複讀說明了做資料庫讀操作的時候可能會出現的問題。

3、髒讀(未送出讀)

防止一個事務讀到另一個事務還沒有送出的記錄。

如:

事務A 事務B

讀取X=100

寫入x=X+100

讀取X=200

事務復原x=100

讀取X=100

事務結束x=100

x鎖 排他鎖 被加鎖的對象隻能被持有鎖的事務讀取和修改,其他事務無法在該對象上加其他鎖,也不能讀取和修改該對象

s鎖 共享鎖 被加鎖的對象可以被持鎖事務讀取,但是不能被修改,其他事務也可以在上面再加s鎖。

封鎖協定:

一級封鎖協定:

在事務修改資料的時候加x鎖,直到事務結束(送出或者復原)釋放x鎖。一級封鎖協定可以有效的防止丢失更新,但是不能防止髒讀不可重複讀的出現。

二級封鎖協定:

在一級封鎖的基礎上事務讀資料的時候加s鎖,讀取之後釋放。二級封鎖協定可以防止丢失更新,髒讀。不能防止不可重複讀。

三級封鎖協定:

在一級封鎖的基礎上事務讀資料的時候加s鎖,直到事務結束釋放。二級封鎖協定可以防止丢失更新,髒讀,不可重複讀。

繼續閱讀