MySQL的臟讀、幻讀、不可重復(fù)讀是什么
簡而言之
臟讀:指讀取了其他事務(wù)尚未提交的數(shù)據(jù),可能導(dǎo)致不一致性。
不可重復(fù)讀:在對數(shù)據(jù)進行讀取的過程中,有其他事務(wù)對數(shù)據(jù)進行了修改(UPDATE、DELETE),導(dǎo)致第二次讀取的結(jié)果與第一次不一致。
幻讀:指一個事務(wù)在進行范圍查詢時,另一個事務(wù)在該范圍內(nèi)進行新增操作(INSERT),導(dǎo)致范圍查詢的結(jié)果數(shù)目不一致。
什么是臟讀
臟讀又稱為無效數(shù)據(jù)讀取,指在數(shù)據(jù)庫訪問中,事務(wù)T1修改了某個數(shù)值,隨后事務(wù)T2讀取了該數(shù)值,而后因某種原因,T1撤銷了對該數(shù)值的修改,導(dǎo)致T2讀取到的數(shù)據(jù)變?yōu)闊o效。
具體而言,臟讀是指一個事務(wù)正在訪問數(shù)據(jù)并對其進行修改,但這些修改尚未提交到數(shù)據(jù)庫中。此時,另一個事務(wù)也訪問該數(shù)據(jù),并使用了它。由于這些數(shù)據(jù)尚未提交,另一個事務(wù)所讀取的數(shù)據(jù)就會成為臟數(shù)據(jù),基于這些臟數(shù)據(jù)所做的操作可能會產(chǎn)生不正確的結(jié)果。
什么是幻讀
幻讀是指在事務(wù)非獨立執(zhí)行時出現(xiàn)的現(xiàn)象,舉例來說,第一個事務(wù)對表中的數(shù)據(jù)進行了修改,涉及到表中的“全部數(shù)據(jù)行”。與此同時,第二個事務(wù)也修改了該表的數(shù)據(jù),插入了“一行新數(shù)據(jù)”。隨后,操作第一個事務(wù)的用戶發(fā)現(xiàn)表中仍然存在未修改的數(shù)據(jù)行,就好像出現(xiàn)了幻覺一般。
一般解決幻讀的方法是通過增加范圍鎖(RangeS)
,將檢測鎖的范圍限定為只讀,這樣便可以避免幻讀的發(fā)生。
值得注意的是,幻讀是不可重復(fù)讀的一種特殊情況:在事務(wù)沒有獲取范圍鎖的情況下執(zhí)行SELECT … WHERE
操作時可能會導(dǎo)致幻讀現(xiàn)象的發(fā)生。
什么是不可重復(fù)讀
不可重復(fù)讀是指在數(shù)據(jù)庫訪問中,一個事務(wù)內(nèi)進行兩次相同的查詢卻返回了不同的數(shù)據(jù)。這種現(xiàn)象是由于系統(tǒng)中其他事務(wù)的提交修改所引起的。例如,事務(wù)T1讀取某一數(shù)據(jù),事務(wù)T2讀取并修改了該數(shù)據(jù),隨后T1為了檢驗讀取值再次讀取該數(shù)據(jù),結(jié)果獲取到不同的數(shù)值。
更通俗易懂的說法是:在一個事務(wù)中多次讀取同一數(shù)據(jù),在該事務(wù)未結(jié)束之前,另一個事務(wù)也訪問同一數(shù)據(jù)。在第一個事務(wù)兩次讀取數(shù)據(jù)之間,由于第二個事務(wù)的修改,導(dǎo)致第一個事務(wù)讀取到的數(shù)據(jù)可能不同,這就導(dǎo)致了在同一個事務(wù)內(nèi)兩次讀取數(shù)據(jù)的結(jié)果不一致,因此稱為不可重復(fù)讀,即原始讀取結(jié)果不可重復(fù)。
擴展知識之事務(wù)隔離級別
臟讀、不可重復(fù)讀和幻讀這三種異?,F(xiàn)象是在SQL-92標(biāo)準(zhǔn)中定義的,同時,SQL-92標(biāo)準(zhǔn)還確定了4種隔離級別來處理這些異常情況,按照嚴(yán)格程度從高到低排列分別為:順序執(zhí)行(Serializable)、可重復(fù)讀(Repeatable reads)、提交讀(Read committed)、未提交讀(Read uncommitted)。