數據庫事務隔離級別

數據庫的事務對數據並行訪問的時候,有可能會出現一些問題,所以數據庫設置了四個不一樣的隔離級別來解決問題。數據庫

在 MySQL 數據庫的隔離級別能夠分爲四層,分別是讀未提交、讀提交、可重複讀和串行化。與之對應出現的問題有髒讀、幻讀、不可重複讀。性能

隔離級別

讀未提交(read uncommited)

一個事務還未提交時,它作的變動就能被其餘的事務看到。學習

讀提交(read commited)

一個事務提交以後,它作的變動纔會被其餘事務看到事務

可重複讀(repeatable read)

一個事務執行過程當中看到的數據,老是跟這個事務啓動時看到的數據是一致的。在此隔離級別下,未提交的事務對其餘事務也是不可見的。it

串行化(serializable)

對同一行記錄,「寫」 會加 「寫鎖」,「讀」 會加 「讀鎖」。當出現讀寫鎖衝突的時候,後訪問的事務必須等前一個事務執行完成,才能繼續執行。
此隔離級別保證了數據的正確性,可是頻繁的加鎖會對性能形成嚴重的影響。table

不一樣的事務隔離級別對應的問題

髒讀

在 「讀未提交」 級別下,未提交的變動被其餘事務看到了,對其餘事務來講,這些未提交的變動就是髒數據,這樣的現象就稱之爲「髒讀」。後臺

不可重複讀

在 「讀提交」 級別下,只有事務提交以後,別的事務才能看到事務作的更改,可是當一個事務 A 在執行過程當中屢次查詢某個值,第一次查詢的時候值爲 v1, 而後在事務 B 把值修改了,當事務 A 再次查詢的時候,就會發現這個值不同了,明明是同一個事務進行的查詢操做,兩次查詢出來的結果卻不一樣,這就是「不可重複讀」並行

幻讀

「幻讀」 與 「不可重複讀」 比較相似,事務 A 查詢某個值,若是不存在,就插入,當事務 A 查詢到不存在以後,事務 B 插入了這個值,事務 A 再去插入的時候就會發現以前查詢不存在的值竟然有了。解決幻讀的方法就是設置事務隔離級別爲「串行化」,即不管讀寫,都對數據加鎖。方法

用下面這個過程來展現一下區別數據

事務A 事務B
啓動事務A,
查詢獲得值1
啓動事務B
查詢獲得值1
將1改成2
查詢獲得值 v1
提交事務B
查詢獲得值 v2
提交事務 A
查詢獲得值 v3
  • 若隔離級別是「讀未提交」,則 v1 的值就是2.這時候事務 B 雖然尚未提交,可是結果已經被 A 看到了。所以, v二、v3 都是 2。
  • 若隔離級別是「讀提交」,則 v1 是 1, v2 的值是 2.事務 B 的更新在提交後才能被 A 看到。因此, v3 的值也是 2.
  • 若隔離級別是「可重複讀」,則 v一、v2 是 1,v3 是 2。在「可重複讀」級別下須要遵循這個要求:事務在執行期間看到的數據先後必須都是一直的。
  • 若隔離級別是「串行化」,則在事務 B 執行「將1改成2」的時候,會被鎖住。知道事務 A 提交以後,事務 B 才能夠繼續執行。因此從 A 的角度看,v一、v2的值是 1,v3 的值是 2.

在事務的隔離級別實現上,數據庫裏面會建立一個視圖,訪問的時候以視圖的邏輯結果爲準。

  • 在「可重複讀」隔離級別下,這個視圖是在事務啓動時建立的,整個事務執行期間都使用這個視圖;
  • 在「讀提交」級別下,這個視圖是在每一個 SQL 語句開始執行的時候建立的;
  • 若是是「讀未提交」級別,直接返回記錄上的最新值,沒有視圖概念;而在「串行化」級別下直接用加鎖的方式來避免並行訪問。

公衆號:沒有夢想的阿巧 後臺回覆 "羣聊",一塊兒學習,一塊兒進步

相關文章
相關標籤/搜索