mysql事務隔離級別案例講解

2020-10-14 19:00:36

目錄

Read Uncommitted(讀取未提交內容)

Read Committed(讀取提交內容)

Repeatable Read(可重讀)

Serializable(可序列化)

Read Uncommitted(讀取未提交內容)案例

Read Committed(讀取提交內容)案例

Repeatable Read(可重讀)案例

Serializable(可序列化)案例


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)資料,而另一個事務卻在此時插入了新的幾列資料,先前的事務在接下來的查詢中,就有幾列資料是未查詢出來的,如果此時插入和另外一個事務插入的資料,就會報錯。

 

Read Uncommitted(讀取未提交內容)案例

開啟A、B兩個使用者端,將A使用者端的隔離級別修改為 讀未提交;

set session transaction isolation level read uncommitted;

A使用者端

檢視當前事務隔離級別

select @@tx_isolation;

A使用者端

B使用者端開啟事務,B使用者端執行修改操作後,不提交;A使用者端查詢資料,

B使用者端

start transaction;

update account set money=5000 where name="aaa";

 

B使用者端事務rollback,發生髒讀現象

A使用者端
 

Read Committed(讀取提交內容)案例

A使用者端設定為讀提交

set session transaction isolation level read committed;

select @@tx_isolation;

B使用者端開啟事務,B使用者端update資料前,A使用者端查詢資料結果,B使用者端update資料後,A使用者端查詢資料結果,B使用者端commit事務,A使用者端查詢資料結果

B使用者端

start transaction;

update account set money=5000 where name="aaa";

commit;

 

A使用者端 

 

 事務中出現了多次select結果不一樣現象稱為不可重複度;

 

Repeatable Read(可重讀)案例

A使用者端設定隔離級別為可重複讀

set session transaction isolation repeatable read;

select @@tx_isolation;

B使用者端開啟事務,A使用者端開啟事務,A使用者端查詢資料,B使用者端update資料,A使用者端查詢資料,B使用者端commit事務,A使用者端查詢資料;

B使用者端

start transaction;

update account set money=500 where name="aaa";

commit;

A使用者端

 

 A事務中對資料查詢的結果都一樣,保證了資料的可重複讀,但是出現事務查詢的結果不是最新的表資料  幻讀現象;

 

Serializable(可序列化)案例

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

A使用者端的事務隔離級別設定為serializable

set session transaction isolation level serializable;

B使用者端開啟事務,執行update操作,不提交、不回滾事務;A使用者端開啟事務查詢資料,發現等待