幻讀(phantom read)
- 前提條件:InnoDB引擎,可重復(fù)讀隔離級別,使用當(dāng)前讀時。
-
表現(xiàn):一個事務(wù)(同一個read view)在前后兩次查詢同一范圍的時候,后一次查詢看到了前一次查詢沒有看到的行。兩點需要說明:
1、在可重復(fù)讀隔離級別下,普通查詢是快照讀,是不會看到別的事務(wù)插入的數(shù)據(jù)的,幻讀只在當(dāng)前讀下才會出現(xiàn)。
2、幻讀專指新插入的行,讀到原本存在行的更新結(jié)果不算。因為當(dāng)前讀的作用就是能讀到所有已經(jīng)提交記錄的最新值。
幻讀的影響
- 會造成一個事務(wù)中先產(chǎn)生的鎖,無法鎖住后加入的滿足條件的行。
- 產(chǎn)生數(shù)據(jù)一致性問題,在一個事務(wù)中,先對符合條件的目標(biāo)行做變更,而在事務(wù)提交前有新的符合目標(biāo)條件的行加入。這樣通過binlog恢復(fù)的數(shù)據(jù)是會將所有符合條件的目標(biāo)行都進(jìn)行變更的。
幻讀產(chǎn)生的原因
- 行鎖只能鎖住行,即使把所有的行記錄都上鎖,也阻止不了新插入的記錄。
如何解決幻讀
- 將兩行記錄間的空隙加上鎖,阻止新記錄的插入;這個鎖稱為間隙鎖。
- 間隙鎖與間隙鎖之間沒有沖突關(guān)系。跟間隙鎖存在沖突關(guān)系的,是往這個間隙中插入一個記錄這個操作。