一致性視圖是啥時(shí)候建立的?
在上篇文章中涉及到了一個(gè)小小的問(wèn)題,就是數(shù)據(jù)庫(kù)事務(wù)的一致性視圖是啥時(shí)候建立的?
這個(gè)問(wèn)題還比較重要,如果沒(méi)搞清楚,可能會(huì)影響我們做實(shí)驗(yàn)的結(jié)果,進(jìn)而得出錯(cuò)誤的結(jié)論,所以今天松哥和大家簡(jiǎn)單聊一聊這個(gè)話(huà)題。
1. 錯(cuò)誤演示
先給大家來(lái)一個(gè)錯(cuò)誤演示。
我們打開(kāi)兩個(gè)會(huì)話(huà)窗口,默認(rèn)情況下隔離級(jí)別是可重復(fù)讀,我們來(lái)看下:
首先在 A 會(huì)話(huà)中查看當(dāng)前 user 表,查看完成后開(kāi)啟事務(wù):
可以看到當(dāng)前 age 是 101。
接下來(lái)在 B 會(huì)話(huà)中修改 age:
可以看到,B 會(huì)話(huà)已經(jīng)修改成功。
接下來(lái)回到 A 會(huì)話(huà)查詢(xún)記錄:
可以看到,A 會(huì)話(huà)的記錄也變了。完整測(cè)試流程如下:
說(shuō)好的可重復(fù)讀呢?
按理說(shuō),可重復(fù)讀就是別的事務(wù)對(duì)數(shù)據(jù)的操作不影響當(dāng)前事務(wù),但是上面這個(gè)案例似乎和我們理解的可重復(fù)讀有出入。
2. 分析
不知道小伙伴們是否還記得可重復(fù)讀的特點(diǎn):
用戶(hù)在另外一個(gè)事務(wù)中執(zhí)行同條 SELECT 語(yǔ)句數(shù)次,結(jié)果總是相同的。
從這個(gè)角度來(lái)說(shuō),第一小節(jié)的案例似乎也沒(méi)有問(wèn)題,因?yàn)槲覀冊(cè)?A 會(huì)話(huà)中執(zhí)行 SELECT 語(yǔ)句多次,查到的結(jié)果也都是相同的,age 都是 102。
但是我們疑惑的是明明 B 會(huì)話(huà)的事務(wù)后開(kāi)啟的,但是我們卻在 A 會(huì)話(huà)中讀取到了 B 的修改,這似乎不應(yīng)該。
這里就涉及到一個(gè)問(wèn)題,事務(wù)的一致性視圖是何時(shí)建立的?
事實(shí)上,我們執(zhí)行的 begin 語(yǔ)句并不是一個(gè)事務(wù)真正的起點(diǎn)。執(zhí)行完 begin 之后,接下來(lái)執(zhí)行的第一句 SQL,事務(wù)才真正啟動(dòng)。
我們稍微修改一下第一小節(jié)的案例:
在 A 會(huì)話(huà)中,事務(wù)開(kāi)啟之后,立馬先執(zhí)行一條 SELECT 語(yǔ)句,然后再去 B 會(huì)話(huà)中做修改,修改完成后再回到 A 會(huì)話(huà)繼續(xù)查詢(xún),此時(shí)發(fā)現(xiàn) B 中的修改對(duì) A 并不可見(jiàn),這個(gè)結(jié)果也符合用戶(hù)在另外一個(gè)事務(wù)中執(zhí)行同條 SELECT 語(yǔ)句數(shù)次,結(jié)果總是相同的。
如果我們想要執(zhí)行完 begin 之后,就立馬開(kāi)啟事務(wù),那么可以通過(guò)如下方式來(lái)執(zhí)行:
- start transaction with consistent snapshot;
這個(gè) SQL 執(zhí)行完之后,事務(wù)立馬就啟動(dòng)了。
接下來(lái),回到第一小節(jié)的案例,我們修改一下事務(wù)啟動(dòng)的命令:
此時(shí),A 會(huì)話(huà)中事務(wù)的查詢(xún)就看不見(jiàn) B 中的修改了。
3.小結(jié)
好啦,一個(gè)小小的案例,希望小伙伴們?cè)谧鰧?shí)驗(yàn)的時(shí)候不要出錯(cuò)。本文涉及到一個(gè)概念叫做一致性視圖,如果大家不熟悉可以參考上篇文章。