數(shù)據(jù)庫的讀現(xiàn)象淺析

“讀現(xiàn)象”是多個(gè)事務(wù)并發(fā)執(zhí)行時(shí),在讀取數(shù)據(jù)方面可能碰到的狀況。先了解它們有助于理解各隔離級(jí)別的含義。其中包括臟讀、不可重復(fù)讀和幻讀。

臟讀

臟讀又稱無效數(shù)據(jù)的讀出,是指在數(shù)據(jù)庫訪問中,事務(wù)T1將某一值修改,然后事務(wù)T2讀取該值,此后T1因?yàn)槟撤N原因撤銷對該值的修改,這就導(dǎo)致了T2所讀取到的數(shù)據(jù)是無效的。

臟讀就是指當(dāng)一個(gè)事務(wù)正在訪問數(shù)據(jù),并且對數(shù)據(jù)進(jìn)行了修改,而這種修改還沒有提交(commit)到數(shù)據(jù)庫中,這時(shí),另外一個(gè)事務(wù)也訪問這個(gè)數(shù)據(jù),然后使用了這個(gè)數(shù)據(jù)。因?yàn)檫@個(gè)數(shù)據(jù)是還沒有提交的數(shù)據(jù),那么另外一個(gè)事務(wù)讀到的這個(gè)數(shù)據(jù)是臟數(shù)據(jù),依據(jù)臟數(shù)據(jù)所做的操作可能是不正確的。

舉例說明:

在下面的例子中,事務(wù)2修改了一行,但是沒有提交,事務(wù)1讀了這個(gè)沒有提交的數(shù)據(jù)?,F(xiàn)在如果事務(wù)2回滾了剛才的修改或者做了另外的修改的話,事務(wù)1中查到的數(shù)據(jù)就是不正確的了。

image.png

在這個(gè)例子中,事務(wù)2回滾后就沒有id是1,age是21的數(shù)據(jù)了。所以,事務(wù)一讀到了一條臟數(shù)據(jù)。

不可重復(fù)讀

不可重復(fù)讀,是指在數(shù)據(jù)庫訪問中,一個(gè)事務(wù)范圍內(nèi)兩個(gè)相同的查詢卻返回了不同數(shù)據(jù)。這是由于查詢時(shí)系統(tǒng)中其他事務(wù)修改的提交而引起的。比如事務(wù)T1讀取某一數(shù)據(jù),事務(wù)T2讀取并修改了該數(shù)據(jù),T1為了對讀取值進(jìn)行檢驗(yàn)而再次讀取該數(shù)據(jù),便得到了不同的結(jié)果。

一種更易理解的說法是:在一個(gè)事務(wù)內(nèi),多次讀同一個(gè)數(shù)據(jù)。在這個(gè)事務(wù)還沒有結(jié)束時(shí),另一個(gè)事務(wù)也訪問該同一數(shù)據(jù)。那么,在第一個(gè)事務(wù)的兩次讀數(shù)據(jù)之間。由于第二個(gè)事務(wù)的修改,那么第一個(gè)事務(wù)讀到的數(shù)據(jù)可能不一樣,這樣就發(fā)生了在一個(gè)事務(wù)內(nèi)兩次讀到的數(shù)據(jù)是不一樣的,因此稱為不可重復(fù)讀,即原始讀取不可重復(fù)。

舉例說明:

在基于鎖的并發(fā)控制中“不可重復(fù)讀(non-repeatable read)”現(xiàn)象發(fā)生在當(dāng)執(zhí)行SELECT 操作時(shí)沒有獲得讀鎖(read locks)或者SELECT操作執(zhí)行完后馬上釋放了讀鎖; 多版本并發(fā)控制中當(dāng)沒有要求一個(gè)提交沖突的事務(wù)回滾也會(huì)發(fā)生“不可重復(fù)讀(non-repeatable read)”現(xiàn)象。

image.png

在這個(gè)例子中,事務(wù)2提交成功,因此他對id為1的行的修改就對其他事務(wù)可見了。但是事務(wù)1在此前已經(jīng)從這行讀到了另外一個(gè)“age”的值。

幻讀

幻讀是指當(dāng)事務(wù)不是獨(dú)立執(zhí)行時(shí)發(fā)生的一種現(xiàn)象,例如第一個(gè)事務(wù)對一個(gè)表中的數(shù)據(jù)進(jìn)行了修改,比如這種修改涉及到表中的“全部數(shù)據(jù)行”。同時(shí),第二個(gè)事務(wù)也修改這個(gè)表中的數(shù)據(jù),這種修改是向表中插入“一行新數(shù)據(jù)”。那么,以后就會(huì)發(fā)生操作第一個(gè)事務(wù)的用戶發(fā)現(xiàn)表中還有沒有修改的數(shù)據(jù)行,就好象發(fā)生了幻覺一樣.一般解決幻讀的方法是增加范圍鎖RangeS,鎖定檢鎖范圍為只讀,這樣就避免了幻讀。

幻讀(phantom read)”是不可重復(fù)讀(Non-repeatable reads)的一種特殊場景:當(dāng)事務(wù)沒有獲取范圍鎖的情況下執(zhí)行SELECT … WHERE操作可能會(huì)發(fā)生“幻影讀(phantom read)”。

舉例說明:

當(dāng)事務(wù)1兩次執(zhí)行SELECT … WHERE檢索一定范圍內(nèi)數(shù)據(jù)的操作中間,事務(wù)2在這個(gè)表中創(chuàng)建了(如INSERT)了一行新數(shù)據(jù),這條新數(shù)據(jù)正好滿足事務(wù)1的“WHERE”子句。


image.png

在這個(gè)例子中,事務(wù)一執(zhí)行了兩次相同的查詢操作。但是兩次操作中間事務(wù)二向數(shù)據(jù)庫中增加了一條符合事務(wù)一的查詢條件的數(shù)據(jù),導(dǎo)致幻讀。

解決方案

要想解決臟讀、不可重復(fù)讀、幻讀等讀現(xiàn)象,那么就需要提高事務(wù)的隔離級(jí)別。但與此同時(shí),事務(wù)的隔離級(jí)別越高,并發(fā)能力也就越低。所以,還需要讀者根據(jù)業(yè)務(wù)需要進(jìn)行權(quán)衡。

參考資料

維基百科
Hollis - 數(shù)據(jù)庫

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

相關(guān)閱讀更多精彩內(nèi)容

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