1. 程式人生 > >資料庫事務隔離級別與鎖機制的實現----不是針對PostgreSQL,而是普遍的原理,來自網際網路,有刪節

資料庫事務隔離級別與鎖機制的實現----不是針對PostgreSQL,而是普遍的原理,來自網際網路,有刪節

文章來自原文連結:

版權歸原作者所有,有刪節,只保留對我理解有幫助的部分。

事務隔離級別通過鎖的實現機制

兩個鎖

排他鎖:

被加鎖的物件只能被持有鎖的事務讀取和修改,其他事務無法在該物件上加其他鎖,也不能讀取和修改該物件。

共享鎖:

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

特別的,對共享鎖: 

如果兩個事務對同一個資源上了共享鎖,事務A想更新該資料,那麼它必須等待事務B釋放其共享鎖。

在運用排他鎖和共享鎖對資料物件加鎖時,還需要約定一些規則,例如何時申請排他鎖或共享鎖、持鎖時間、何時釋放等。稱這些規則為封鎖協議(Locking Protocol)。對封鎖方式規定不同的規則,就形成了各種不同的封鎖協議。


封鎖協議


一級封鎖協議 (對應 read uncommitted)

一級封鎖協議是:

事務在對需要修改的資料上面(就是在發生修改的瞬間) 對其加共享鎖(其他事務不能更改,但是可以讀取-導致“髒讀”),直到事務結束才釋放。事務結束包括正常結束(COMMIT)和非正常結束(ROLLBACK)。

一級封鎖協議不能避免丟失更新,髒讀,不可重複讀,幻讀!


二級封鎖協議 (對應read committed)

二級封鎖協議是:

1)事務在對需要更新的資料 上(就是發生更新的瞬間) 加排他鎖 (直到事務結束) , 防止其他事務讀取未提交的資料,這樣,也就避免了 “髒讀” 的情況。

2)事務對當前被讀取的資料 上面加共享鎖(當讀到時加上共享鎖),一旦讀完該行,立即釋放該 該行的共享鎖 – 從資料庫的底層實現更深入的來理解,既是,資料庫會對遊標當前的資料上加共享鎖 , 但是當遊標離開當前行的時候,立即釋放該行的共享鎖。


二級封鎖協議除防止了“髒讀”資料,但是不能避免丟失更新,不可重複讀,幻讀 。

但在二級封鎖協議中,由於讀完資料後立即釋放共享鎖,所以它不能避免可重複讀 ,同時它也不能避免丟失更新 ,如果事務A、B同時獲取資源X,然後事務A先發起更新記錄X,那麼 事務B 將等待事務 A 執行完成,然後獲得記錄X 的排他鎖,進行更改。這樣事務 A 的更新將會被丟失。 具體情況如下:


如果要避免 丟失更新,我們需要額外的操作, 對凡是讀到的資料加共享鎖和排他鎖 ,這個往往需要程式設計師自己程式設計實現,比如在Oracle 中,需要加 SELECT FOR UPDATE 語句,表明,凡是該事務讀到的資料,額外的加上排他鎖,防止其他資料同一時間獲取相同資料,這樣就防止了丟失更新 

三級封鎖協議 (對應reapetable read )


三級封鎖協議是:

二級封鎖協議加上事務在讀取資料的瞬間 必須先對其加共享鎖 ,但是直到事務結束才釋放 ,這樣保證了可重複讀(既是其他的事務職能讀取該資料,但是不能更新該資料)。

三級封鎖協議除防止了“髒”資料,不可重複讀和丟失更新。但是這種情況不能避免幻讀。由於該封鎖協議只是對某行資料加鎖,因此在事務 A 沒有完成之前,事務 B 可以新增資料(因為不是對鎖住的這一行操作),那麼 當事務 A 再次讀取的時候,事務B 新增的資料會被讀取到,這樣,在該封鎖協議下,幻讀 就產生了。

注:原文說該封鎖協議不能避免丟失更新,但我認為是可以避免的。因為無論共享鎖還是排它鎖,在該事務隔離等級下,其持有時間都是整個事務週期,所以無論讀還是寫某一行記錄都是獨佔的,不可能存在事務A和B併發讀取資料的情況,同時只有一個事務能讀取並修改資料。因此應該不會造成丟失更新。

進階:repeatable read 導致死鎖的情況(即便是 不同的資源在相同的順序下獲取)。 比如 事務1 讀取 A,同時 事務2 也讀取 A,那麼事務1和事務2 同時對 A 上了共享鎖,然後事務1 要UPDATE A,而此時 事務2 也要 UPDATE A,這個時候 事務1 等待 事務2 釋放其在 A 上的共享鎖,然後 事務2 要等待 事務1 釋放其在 A 上的共享鎖,這樣,事務1 和 事務2 相互等待,產生死鎖!(SQL Server/DB2 裡面有 UPDATE LOCK 可以解決這種情況,具體的思路是,在 repeatable read 的情況下,將讀取的資料 上的 UPDATE 鎖,介於 共享鎖 和 排他鎖之間的一種鎖,該鎖的作用是 當出現上面這種情況後,事務1 和 事務2 對 A 上的是 UPDATE 鎖,那麼誰先 要修改 A,那麼該事務就會將 UPDATE 鎖可以順利升級為 排他鎖對該資料進行修改!)


最強封鎖協議(對應Serialization)


四級封鎖協議是對三級封鎖協議的增強,其實現機制也最為簡單,直接對事務中所讀取或者更改的資料所在的表加表鎖,也就是說,其他事務不能 讀寫 該表中的任何資料。這樣所有的 髒讀,不可重複讀,幻讀 ,都得以避免!