1. 程式人生 > >mysql關於資料庫事務隔離級別測試(包含例項測試語句,及測試結果對比)

mysql關於資料庫事務隔離級別測試(包含例項測試語句,及測試結果對比)

1、知識點;

事務的四大特性 ACID ;

 原子性(Atomic):事務是一個整體(無論在該事務中操作任何CRUD),要不全部執行,要不全部不執行。(資料庫能夠進行操作的最小的邏輯單元)

一致性(Consistent):組成一個事務的操作是CRUD,要麼全部成功,要麼全部失敗(類似原子性的後續補充)。

隔離性(Insulation):事務之間的隔離(比如:AB兩個事物,併發時,A事務在讀取資料時,僅能讀取B事務操作之間的資料,或是B事務操作之後的資料,無法讀取操作中的資料)

永續性(Duration):事務完成後對資料的修改時永久的。

事務的四大隔離級別;

讀未提交(read uncommitted):一個事務可以讀到另一個事務未提交的結果(所有的問題均會出現(髒讀、不可重複讀、幻讀))

讀提交(read committed ):只有一個事務被提交後,其更新結果才能被其他事務讀取到(出現問題(不可重複讀、幻讀),解決(髒讀))

可重複讀(repeatable read):在一個事務中,對於同一份資料的讀取結果總是相同的,無論是否有其他事務對這份資料進行操作,以及這個事務是否提交。(解決(髒讀、不可重複讀、幻讀)) (mysql預設級別)

序列化(serializable):事務序列化執行,隔離級別最高,犧牲了系統的併發性。可以解決併發事務的所有問題。

不同隔離級別可能導致的問題:髒讀、不可重複讀,幻讀

併發問題彙總:

髒讀:一個事務讀取到另一個事務未提交的資料。

不可重複讀:一個事務在不同時刻讀取到不同的資料。

幻讀:一個事務在讀取資料後,(另一個事務執行新增操作後)。由於不可重複讀的問題解決,所以該事務讀取不到新新增的資料,所以在新增同樣主鍵的資料時會報錯,

2、例項資料及測試

備註:建議開始前先將會話的自動提交關閉:

命令:$>set session autocommit = 0;  -- 關閉會話事務的自動提交

$>show session variables like "autocommited" ;  -- 檢視事務提交自動化狀態。

1>讀未提交:最低的隔離界別,三大問題均存在(髒讀、不可重複讀、幻讀)

實現簡述:A會話 (repeatable  read )、B會話(read uncommitted) 。A會話中建立事務,然後修改資料,但不提交,B會話可以讀到A未提交的資料:  以下按操作順序依次執行。

A會話:

檢視A的會話界別

使用資料庫

開啟事務

修改資料,但並未提交

 

B會話(A不關閉,重新啟動一個會話);

檢視當前隔離界別

不修改隔離界別,發現數據並未讀取到未提交的資料。

 設定隔離界別為讀未提交

讀取到未提交的資料。

2>讀提交(存在問題:不可重複讀)

實現簡述:在1的基礎上,修改B會話的隔離界別為read commited ,發現髒讀會被解決(及讀取不到A會話未提交的資料)。

B會話:

設定隔離界別為讀已提交。髒讀被解決。

問題:可重複讀。

問題描述:A會話中,在B會話對資料進行第一次查詢後,對該資料進行修改並提交 。B會話再對該資料進行查詢,發現第二次和

第一次查詢出來的資料不一致。

B會話:

設定隔離界別為讀提交,開啟事務,第一次查詢資料。

A會話

查詢資料、開啟事務。修改資料。

提交資料。

檢視資料已修改。

B會話

兩次查詢資料不一致。

3>可重複讀

問題解決描述:在2的基礎上,設定B會話的隔離界別為repeatable read,發現B會話再第一二次讀取的資料一致。

B會話:

設定隔離界別為可重複讀

A會話

修改資料

B會話

發現在同一個事物中兩次讀取資料一致

提交事務後,讀取到修改後的資料。

問題描述:幻讀,A會話,查詢資料時,發現主鍵id的數值到1,然後B開啟事務,新增一個主鍵id為2的資料,之後提交資料。然後A會話,提交主鍵是2的資料,發現報(主鍵id為2的資料已存在)。但A缺沒讀取到,出現了幻讀。

A會話

B會話

建立資料

A會話

第二次查詢資料(不可重複讀)後,新增報錯,已存在 A會話出現幻讀。

4>序列化(序列化(悲觀鎖))(鎖行) (讀佔寫鎖)

問題描述:設定A會話為序列化(serializable),然後建立事務,查詢users表後,在B會話中建立事務,往users表中新增資料發現被塞住了,只要A會話中的事務提交了,B會話才可新增成功(同樣,A建立事務後(不查詢users表),B建立事務後,新增資料到users表中(可成功,不提交事務,然後A會話查詢users表,發現被塞住了,只有B會話的事務提交後,才可提交成功!)。避免了幻讀,但很影響效能、

A會話

設定事務為序列化

建立事務查詢users表

B會話

建立事務,可查詢users表,但新增資料時被塞住

A會話提交資料

B會話中的新增操作執行(由於本機操作時間慢了,所以超時,速度快點會執行,然後B會話提交事務即可)。