事務(wù)-InnoDB,快照讀,在RR和RC下有何差異?

快照讀(Snapshot Read)

MySQL數(shù)據(jù)庫,InnoDB存儲引擎,為了提高并發(fā),使用MVCC機(jī)制,在并發(fā)事務(wù)時(shí),通過讀取數(shù)據(jù)行的歷史數(shù)據(jù)版本,不加鎖,來提高并發(fā)的一種不加鎖一致性讀(Consistent Nonlocking Read)。

讀提交(Read Committed)

數(shù)據(jù)庫領(lǐng)域,事務(wù)隔離級別的一種,簡稱RC

它解決“讀臟”問題,保證讀取到的數(shù)據(jù)行都是已提交事務(wù)寫入的

它可能存在“讀幻影行”問題,同一個(gè)事務(wù)里,連續(xù)相同的read可能讀到不同的結(jié)果集

可重復(fù)讀(Repeated Read)

數(shù)據(jù)庫領(lǐng)域,事務(wù)隔離級別的一種,簡稱RR

它不但解決“讀臟”問題,還解決了“讀幻影行”問題,同一個(gè)事務(wù)里,連續(xù)相同的read讀到相同的結(jié)果集

讀提交(RC),可重復(fù)讀(RR)兩個(gè)不同的事務(wù)的隔離級別下,快照讀有什么不同呢?

先說結(jié)論

事務(wù)總能夠讀取到,自己寫入(update /insert /delete)的行記錄

RC下,快照讀總是能讀到最新的行數(shù)據(jù)快照,當(dāng)然,必須是已提交事務(wù)寫入的

RR下,某個(gè)事務(wù)首次read記錄的時(shí)間為T,未來不會(huì)讀取到T時(shí)間之后已提交事務(wù)寫入的記錄,以保證連續(xù)相同的read讀到相同的結(jié)果集

畫外音:可以看到

(1)和并發(fā)事務(wù)的開始時(shí)間沒關(guān)系,和事務(wù)首次read的時(shí)間有關(guān);

(2)由于不加鎖,和互斥關(guān)系也不大;

這些就能解答《InnoDB的快照讀,到底和什么相關(guān)?》中的問題了,InnoDB表:

t(id PK, name);

表中有三條記錄:

1, shenjian

2, zhangsan

3, lisi

case 1,兩個(gè)并發(fā)事務(wù)A,B執(zhí)行的時(shí)間序列如下(A先于B開始,B先于A結(jié)束):

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:假設(shè)事務(wù)的隔離級別是可重復(fù)讀RR,事務(wù)A中的三次查詢,A2, A3, A4分別讀到什么結(jié)果集?

回答:RR下

(1)A2讀到的結(jié)果集肯定是{1, 2, 3},這是事務(wù)A的第一個(gè)read,假設(shè)為時(shí)間T;

(2)A3讀到的結(jié)果集也是{1, 2, 3},因?yàn)锽還沒有提交;

(3)A4讀到的結(jié)果集還是{1, 2, 3},因?yàn)槭聞?wù)B是在時(shí)間T之后提交的,A4得讀到和A2一樣的記錄;

提問2:假設(shè)事務(wù)的隔離級別是

讀提交RC,A2, A3, A4又分別讀到什么結(jié)果集呢?

回答:RC下

(1)A2讀到的結(jié)果集是{1, 2, 3};

(2)A3讀到的結(jié)果集也是{1, 2, 3},因?yàn)锽還沒有提交;

(3)A4讀到的結(jié)果集還是{1, 2, 3, 4},因?yàn)槭聞?wù)B已經(jīng)提交;

case 2,仍然是上面的兩個(gè)事務(wù),只是A和B開始時(shí)間稍有不同(B先于A開始,B先于A結(jié)束):

? ? ? ?? 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:假設(shè)事務(wù)的隔離級別是可重復(fù)讀RR,事務(wù)A中的三次查詢,A2, A3, A4分別讀到什么結(jié)果集?

提問4:假設(shè)事務(wù)的隔離級別是讀提交RC,A2, A3, A4的結(jié)果集又是什么呢?

回答:事務(wù)的開始時(shí)間不一樣,不會(huì)影響“快照讀”的結(jié)果,所以結(jié)果集和case 1一樣。

case 3,仍然是并發(fā)的事務(wù)A與B(A先于B開始,B先于A結(jié)束):

A1: start transaction;

B1: start transaction;

B2: insert into t values (4, wangwu);

B3: commit;

A2: select * from t;

提問5:假設(shè)事務(wù)的隔離級別是可重復(fù)讀RR,事務(wù)A中的A2查詢,結(jié)果集是什么?

提問6:假設(shè)事務(wù)的隔離級別是讀提交RC,A2的結(jié)果集又是什么呢?

回答:在RR下,

A2是事務(wù)A的第一個(gè)read,假設(shè)為時(shí)間T,它能讀取到T之前提交事務(wù)寫入的數(shù)據(jù)行,故結(jié)果集為{1, 2, 3, 4}。在RC下,沒有疑問,一定是{1, 2, 3, 4}。

case 4,事務(wù)開始的時(shí)間再換一下(B先于A開始,B先于A結(jié)束):

? ? ? ?? B1: start transaction;

A1: start transaction;

B2: insert into t values (4, wangwu);

B3: commit;

A2: select * from t;

提問7:假設(shè)事務(wù)的隔離級別是可重復(fù)讀RR,事務(wù)A中的A2查詢,結(jié)果集是什么?

提問8:假設(shè)事務(wù)的隔離級別是讀提交RC,A2的結(jié)果集又是什么呢?

回答:事務(wù)的開始時(shí)間不一樣,不會(huì)影響“快照讀”的結(jié)果,所以結(jié)果集和case 3一樣。


啰嗦說了這么多,用昨天一位網(wǎng)友“山峰”同學(xué)的話總結(jié)

RR下,事務(wù)在第一個(gè)Read操作時(shí),會(huì)建立Read View

RC下,事務(wù)在每次Read操作時(shí),都會(huì)建立Read View

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容