資料庫事務隔離級別(二) 之 典例篇

2021-07-31 11:31:49 字數 3445 閱讀 1381

sql標準定義了4類隔離級別,包括了一些具體規則,用來限定事務內外的哪些改變是可見的,哪些是不可見的。低階別的隔離級一般支援更高的併發處理,並擁有更低的系統開銷。

read uncommitted(讀取未提交內容)

在該隔離級別,所有事務都可以看到其他未提交事務的執行結果。本隔離級別很少用於實際應用,因為它的效能也不比其他級別好多少。讀取未提交的資料,也被稱之為髒讀(dirty read)。

read committed(讀取提交內容)

這是大多數資料庫系統的預設隔離級別(但不是mysql預設的)。它滿足了隔離的簡單定義:乙個事務只能看見已經提交事務所做的改變。這種隔離級別也支援所謂的不可重複讀(nonrepeatable read),因為同一事務的其他例項在該例項處理其間可能會有新的commit,所以同一select可能返回不同結果。

repeatable read(可重讀)

這是mysql的預設事務隔離級別,它確保同一事務的多個例項在併發讀取資料時,會看到同樣的資料行。不過理論上,這會導致另乙個棘手的問題:幻讀(phantom read)。簡單的說,幻讀指當使用者讀取某一範圍的資料行時,另乙個事務又在該範圍內插入了新行,當使用者再讀取該範圍的資料行時,會發現有新的「幻影」行。innodb和falcon儲存引擎通過多版本併發控制(mvcc,multiversion concurrency control)機制解決了該問題。

serializable(可序列化)

這是最高的隔離級別,它通過強制事務排序,使之不可能相互衝突,從而解決幻讀問題。簡言之,它是在每個讀的資料行上加上共享鎖。在這個級別,可能導致大量的超時現象和鎖競爭。

這四種隔離級別採取不同的鎖型別來實現,若讀取的是同乙個資料的話,就容易發生問題。例如:

髒讀(drity read):某個事務已更新乙份資料,另乙個事務在此時讀取了同乙份資料,由於某些原因,前乙個rollback了操作,則後乙個事務所讀取的資料就會是不正確的。

不可重複讀(non-repeatable read):在乙個事務的兩次查詢之中資料不一致,這可能是兩次查詢過程中間插入了乙個事務更新的原有的資料。

幻讀(phantom read):在乙個事務的兩次查詢中資料筆數不一致,例如有乙個事務查詢了幾列(row)資料,而另乙個事務卻在此時插入了新的幾列資料,先前的事務在接下來的查詢中,就會發現有幾列資料是它先前所沒有的。

下面,將利用mysql的客戶端程式,分別測試幾種隔離級別。測試資料庫為test,表為tx;表結構: id

intnum

int兩個命令列客戶端分別為a,b;不斷改變a的隔離級別,在b端修改資料。

(一)、將a的隔離級別設定為read uncommitted(未提交讀)

在b未更新資料之前:

客戶端a:

b更新資料:

客戶端b:

客戶端a:

經過上面的實驗可以得出結論,事務b更新了一條記錄,但是沒有提交,此時事務a可以查詢出未提交記錄。造成髒讀現象。未提交讀是最低的隔離級別。

(二)、將客戶端a的事務隔離級別設定為read committed(已提交讀)

在b未更新資料之前:

客戶端a:

b更新資料:

客戶端b:

客戶端a:

經過上面的實驗可以得出結論,已提交讀隔離級別解決了髒讀的問題,但是出現了不可重複讀的問題,即事務a在兩次查詢的資料不一致,因為在兩次查詢之間事務b更新了一條資料。已提交讀只允許讀取已提交的記錄,但不要求可重複讀。

(三)、將a的隔離級別設定為repeatable read(可重複讀)

在b未更新資料之前:

客戶端a:

b更新資料:

客戶端b:

客戶端a:

b插入資料:

客戶端b:

客戶端a:

由以上的實驗可以得出結論,可重複讀隔離級別只允許讀取已提交記錄,而且在乙個事務兩次讀取乙個記錄期間,其他事務部的更新該記錄。但該事務不要求與其他事務可序列化。例如,當乙個事務可以找到由乙個已提交事務更新的記錄,但是可能產生幻讀問題(注意是可能,因為資料庫對隔離級別的實現有所差別)。像以上的實驗,就沒有出現資料幻讀的問題。

(四)、將a的隔離級別設定為可序列化(serializable)

a端開啟事務,b端插入一條記錄

事務a端:

事務b端:

因為此時事務a的隔離級別設定為serializable,開始事務後,並沒有提交,所以事務b只能等待。

事務a提交事務:

事務a端

事務b端

serializable完全鎖定字段,若乙個事務來查詢同乙份資料就必須等待,直到前乙個事務完成並解除鎖定為止。是完整的隔離級別,會鎖定對應的資料**,因而會有效率的問題。

資料庫事務隔離級別(一) 之 概念篇

資料庫事務的隔離級別有4個,由低到高依次為read uncommitted read committed repeatable read serializable,這四個級別可以逐個解決髒讀 不可重複讀 幻讀這幾類問題。可能出現 不會出現 髒讀不可重複讀 幻讀read uncommitted rea...

資料庫事務隔離級別

資料庫事務的隔離級別有4個,由低到高依次為read uncommitted read committed repeatable read serializable,這四個級別可以逐個解決髒讀 不可重複讀 幻讀這幾類問題。可能出現 不會出現 髒讀不可重複讀 幻讀read uncommitted rea...

資料庫事務隔離級別

資料庫事務的隔離級別有4個,由低到高依次為read uncommitted read committed repeatable read serializable,這四個級別可以逐個解決髒讀 不可重複讀 幻讀這幾類問題。可能出現 不會出現 髒讀不可重複讀 幻讀read uncommitted rea...