資料庫事務及其隔離級別

weixin_34146805發表於2017-10-31

資料庫事務

        在計算機中,通常的事務都是指資料庫事務。除此之外還包括java中的事務,jdbc事務,spring中的事務和hibernate事務。【欠】

        事務指的是一組滿足ACID四個性質的一組操作序列。即原子性(Automaty)、一致性(consistency)、隔離性(isolation)、永續性(durability)。其中資料“一致性”是最終目標,其他的特性都是為了達到這個目標的措施、要求或手段。【理解為啥保證一致性需要其他三個】


資料庫併發

        資料庫的併發可以類比java的併發,即多個事務同時對一段資料進行操作。並且和java程式採用物件鎖機制進行執行緒同步類似,DBMS採用資料庫鎖機制保證事務的隔離性。當多個事務試圖對相同的資料進行操作時,只有持有鎖的事務才能運算元據。而資料庫為了簡化使用者使用鎖的操作,設定了隔離級別,每一種隔離級別都是由相應的鎖機制實現的。這就允許使用者通過設定隔離級別,使資料庫分析SQL語句,自動為某行資料或某表加上適合的鎖。隔離級別約高,越能保證資料完整性和一致性,資料的併發性將會越低。當隔離級別達到最強時,事務將順序訪問資料。

        首先介紹資料庫中的鎖機制,再介紹由鎖機制實現的各種隔離級別。

(1)資料庫鎖

        資料庫的鎖關係如下圖所示。

7388797-0567d3d225317db6.png

        若事務為某行資料加上了共享鎖,則會防止其他事物的排它鎖,允許其他共享鎖定。若是排它鎖,則會防止排它鎖和共享鎖。實質上就是能實現併發的讀,讀寫,寫寫都是序列化的。

        以上是在鎖定的關係上看的鎖的定義;還可以在加鎖物件的層面上定義鎖,可分為表鎖定、行鎖定。

(2)隔離級別

        事務併發操作會導致三類問題,對應四種隔離級別。以下從隔離級別層面介紹各級別可解決的問題、會產生的問題及其鎖的機制。

·讀未提交

加鎖機制為:讀--不加鎖,寫--行共享鎖

問題:髒讀。由隔離級別的名稱“讀未提交”即可知,髒讀指的是事務A讀到了事務B更改的未提交的資料,之後事務B又將更改操作rollback了,事務A讀到的資料就是髒資料,即為髒讀。

問題原因:1.由於寫操作只對某行資料加了共享鎖,導致寫事務在事務未提交之前,其他事務也可以訪問該資料。2.讀操作未加任何鎖,讀的過程也可能發生寫操作。

·讀已提交

加鎖機制為:讀--行共享鎖,寫--行排它鎖,鎖在完成對該行資料的操作時釋放。(可解決髒讀問題,因為讀的過程中不允許寫操作)

問題:不可重複讀。不可重複讀指的是在同一事務A中,對該行資料進行了兩次讀訪問,兩次讀取的結果不一致的問題(主要指內容,特指某行資料)。

問題原因:當第一次讀完成後,事務A釋放了該行資料的共享鎖,此時事務B對該行資料進行更改(加上排它鎖),並提交事務【???事務的更新操作是會在事務提交之後才會釋放鎖嗎。感覺是持久化到資料庫之後才算是寫完了,才會釋放鎖】。此時,事務A繼續進行第二次讀訪問,就會發現兩次讀取的結果不一致,導致不可重複的的問題。

·可重複讀

加鎖機制為:讀--行共享鎖,寫--行排它鎖,鎖在完成事務提交時釋放。(可解決不可重複讀問題,因為在同一個事務的兩次讀寫完成之前,不允許進行寫操作)

問題:幻讀。幻讀指的是在同一事務A中,用同樣的操作讀取兩次,得到的記錄數不相同(主要指數量,一般是查詢時)。

問題原因:只在行上加了鎖,但不能控制表中其他資料的變化。例如,當事務A使用某一條件查詢資料時,得到結果集是10條記錄,此時事務B執行insert操作(不影響事務A在某一行加上的鎖),剛好插入的資料也滿足查詢條件,那麼當事務A再查詢時,就會發現記錄數變成了11,即為髒讀。

·可序列化

加鎖機制為:讀--表共享鎖,寫--表排它鎖(可解決幻讀問題,因為在同一個事務的兩次查詢提交之前,不允許對錶進行任何操作)

問題:無敵了,事務順序執行,沒有併發問題。

(3)預設隔離級別

Oracle:讀已提交

MySql:可重複讀


仍然存在的幾個問題

1.鎖與隔離機制的關係是:通過鎖實現隔離級別嗎?實現資料庫的自動加鎖?

2.若1成立,鎖是都使用悲觀鎖嗎,樂觀鎖在其中發揮的作用是什麼?

3.樂觀鎖應用場景我知道,使用樂觀鎖的時候是要關閉隔離級別嗎?

4.讀取操作可在讀完不提交事務時釋放鎖,更新事務釋放行鎖的時機是?未提交事務前可以釋放行鎖嗎?如果可以的話仍然存在髒讀。。

5.第一類丟失更新,第二類丟失更新。。

相關文章