1. 程式人生 > >資料庫的四種隔離級別的實現方式

資料庫的四種隔離級別的實現方式

之前看了一段時間的資料庫。對於資料庫的四種隔離級別一直有疑惑,很多人對於四種隔離級別所面對的情況說法也不一致,下面我說一下我的理解。

說道資料庫的四種隔離級別,就要先說資料庫的ACID,原子性,一致性,隔離性和永續性,這四種隔離級別就是針對資料庫的隔離性,下面針對資料庫的隔離性來說說資料庫會遇到什麼問題,以及每一種隔離級別到底解決了什麼問題。

針對隔離性遇到的問題如下:

1.    髒讀(如有事務A和B,A讀取了B未提交的資料)

2.    不可重複讀(如有事務A和B,A負責讀取,B負責寫入,A連續讀的過程中B寫入了一次,A前後兩次讀出來的資料不一樣)

3.    丟失更新(如有事務A和B,AB均寫入資料,A寫入的資料被B覆蓋)

4.    幻讀(如有事務A和B,A修改表內資料的過程中,B向表內插入了一條資料,A修改完後發現數據並沒有被全部修改完)

針對這以上四種問題,產生了以下四種隔離級別(其實可以算是3種,第一種並沒有處理以上問題),在說隔離級別之前先簡單介紹下實現隔離級別的兩種鎖模式:共享鎖和排他鎖,這兩種鎖都是悲觀鎖,共享鎖也叫S鎖,是一種讀鎖,當一個事物獲得了一條資料的共享鎖,其它事務也能獲得該共享鎖,但不能獲得排他鎖,表明其它事務可讀,但不可寫。排他鎖也叫X鎖,是一種寫鎖,當一個事務對臨界區加上排他鎖,其它事務就不能獲得該臨界區的任何鎖(共享鎖,排他鎖)。總結一下就是共享鎖保證大家可以一起讀,但只能一個人寫,排他鎖保證只能一個人去處理資料,其他人不能讀也不能寫。

1.read uncommitted(未提交讀):其實我覺得翻譯成未提交讀很不好,應該根據字面理解翻譯成在當前隔離級別下,會讀取到沒有提交的資料會好得多,在這種模式下,對比4種問題就會發現1-4的問題均解決不了,但這種模式也不是說完全沒加鎖,在讀取時是不會加鎖的,但在更新資料時,對其加行級共享鎖(其它事務不能更改,但可以讀取,導致髒讀),事務結束時釋放。這種隔離級別未處理任何以上4個問題。

舉例說明:

事務A讀取某行記錄時,事務B也能對這行記錄讀取更新,當事務B更新記錄時,事務A讀取到事務B修改的版本,即使事務B未提交。

事務A和B不能同時更新(共享鎖保證A獲取共享鎖時A能讀寫資料,B能獲取共享鎖能讀,不能寫)

2.read conmmitted(提交讀):還是說下我的理解翻譯:這種隔離級別表示讀取的資料是已提交成功的,解決了髒讀問題,解決方式是給寫資料加行級排他鎖,這樣寫過程是無法讀取的,直到事務處理完畢才釋放排他鎖,給讀的資料加行級共享鎖,這樣讀的時候也是無法寫的,但是一旦讀完該行就釋放共享鎖。這種模式下雖然處理了髒讀,但是並沒有處理丟失更新和不可重複讀的問題。

舉例說明:

事務A負責讀,事務B負責寫,A讀完資料後釋放共享鎖,B更新資料,事務還未結束,A再讀,兩次得到資料不一樣,產生不可重複讀的問題。

同理,事務A獲取共享鎖,更新資料,然後釋放共享鎖,B此時獲得排他鎖,再更新資料,A的資料就可能被覆蓋,產生更新丟失的問題。

3.reapetable read(可重複讀):理解翻譯:在這種隔離級別下可以重複的讀取資料了,顧名思義,解決了不可重複讀的問題,同時也解決了更新丟失的問題。解決辦法:給寫的資料加行級排他鎖,事務結束釋放,給讀的資料加行級共享鎖,事務結束後釋放。這種模式還是沒有處理幻讀的問題

舉例說明:

事務A負責讀,事務B負責寫,A讀完資料後等事務結束才釋放共享鎖,B更新資料,直到事務結束,A再讀,兩次得到資料均為A第一次讀到的資料,解決不可重複讀的問題。

事務A負責讀,只為讀取的資料加行級共享鎖,B在A讀過程中向表單中插入新資料,A沒有處理到新插入的資料,產生幻讀。

4.serializable (序列化):這個沒有什麼理解翻譯,直接看實現就好了,實現也很簡單,事務讀資料則加表級共享鎖,事務寫資料則加表級排他鎖,幻讀問題也得到了解決