1. 程式人生 > 其它 >事務隔離級別在RR和RC下有何差異

事務隔離級別在RR和RC下有何差異

事務隔離級別在RR和RC下有何差異

為了保證文章知識體系的完整性,先簡單解釋下快照讀,讀提交,可重複讀。

快照讀(Snapshot Read)
MySQL資料庫,InnoDB儲存引擎,為了提高併發,使用MVCC機制,在併發事務時,通過讀取資料行的歷史資料版本,不加鎖,來提高併發的一種不加鎖一致性讀(Consistent Nonlocking Read)。

 

讀提交(Read Committed)
資料庫領域,事務隔離級別的一種,簡稱RC
它解決“讀髒”問題,保證讀取到的資料行都是已提交事務寫入的
它可能存在“讀幻影行”問題,同一個事務裡,連續相同的read可能讀到不同的結果集

 

可重複讀(Repeated Read)
資料庫領域,事務隔離級別的一種,簡稱RR
它不但解決“讀髒”問題,還解決了“讀幻影行”問題,同一個事務裡,連續相同的read讀到相同的結果集

 

在讀提交(RC),可重複讀(RR)兩個不同的事務的隔離級別下,快照讀有什麼不同呢?

先說結論:

  1. 事務總能夠讀取到,自己寫入(update /insert /delete)的行記錄
  2. RC下,快照讀總是能讀到最新的行資料快照,當然,必須是已提交事務寫入的
  3. RR下,某個事務首次read記錄的時間為T,未來不會讀取到T時間之後已提交事務寫入的記錄,以保證連續相同的read讀到相同的結果集

畫外音:可以看到

(1) 和併發事務的開始時間沒關係,和事務首次read的時間有關;
(2) 由於不加鎖,和互斥關係也不大;

例子,InnoDB表:
t(id PK, name);
表中有三條記錄:
1, wangyi
2, zhangsan
3, lisi

case 1,兩個併發事務A,B執行的時間序列如下(A先於B開始,B先於A結束):

A1: start transaction;
B1: start transaction;
A2: select * from t;
B2: insert into t values (4, wangwu);
A3: select * from t;
B3: commit;
A4: select * from t;

提問1:假設事務的隔離級別是可重複讀RR,事務A中的三次查詢,A2, A3, A4分別讀到什麼結果集?

提問2:假設事務的隔離級別是讀提交RC,A2, A3, A4又分別讀到什麼結果集呢?

回答:

RR下
(1)A2讀到的結果集肯定是{1, 2, 3},這是事務A的第一個read,假設為時間T;
(2)A3讀到的結果集也是{1, 2, 3},因為B還沒有提交;
(3)A4讀到的結果集還是{1, 2, 3},因為事務B是在時間T之後提交的,A4得讀到和A2一樣的記錄;

RC下
(1)A2讀到的結果集是{1, 2, 3};
(2)A3讀到的結果集也是{1, 2, 3},因為B還沒有提交;
(3)A4讀到的結果集還是{1, 2, 3, 4},因為事務B已經提交;

case 2,仍然是上面的兩個事務,只是A和B開始時間稍有不同(B先於A開始,B先於A結束):

B1: start transaction;
A1: start transaction;
A2: select * from t;
B2: insert into t values (4, wangwu);
A3: select * from t;
B3: commit;
A4: select * from t;

提問3:假設事務的隔離級別是可重複讀RR,事務A中的三次查詢,A2, A3, A4分別讀到什麼結果集?
提問4:假設事務的隔離級別是讀提交RC,A2, A3, A4的結果集又是什麼呢?

回答:事務的開始時間不一樣,不會影響“快照讀”的結果,所以結果集和case 1一樣。

case 3,仍然是併發的事務A與B(A先於B開始,B先於A結束):

A1: start transaction;
B1: start transaction;
B2: insert into t values (4, wangwu);
B3: commit;
A2: select * from t;

提問5:假設事務的隔離級別是可重複讀RR,事務A中的A2查詢,結果集是什麼?
提問6:假設事務的隔離級別是讀提交RC,A2的結果集又是什麼呢?

回答:

在RR下,A2是事務A的第一個read,假設為時間T,它能讀取到T之前提交事務寫入的資料行,故結果集為{1, 2, 3, 4}。

在RC下,沒有疑問,一定是{1, 2, 3, 4}。

case 4,事務開始的時間再換一下(B先於A開始,B先於A結束):

B1: start transaction;
A1: start transaction;
B2: insert into t values (4, wangwu);
B3: commit;
A2: select * from t;

提問7:假設事務的隔離級別是可重複讀RR,事務A中的A2查詢,結果集是什麼?
提問8:假設事務的隔離級別是讀提交RC,A2的結果集又是什麼呢?
回答:事務的開始時間不一樣,不會影響“快照讀”的結果,所以結果集和case 3一樣。

總結:

RR下,事務在第一個Read操作時,會建立Read View
RC下,事務在每次Read操作時,都會建立Read View