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