幻讀指的是事務中讀取到的記錄數量不一致,只有RR可重復讀事務隔離級別才存在幻讀。 並且幻讀需要當前讀才會出現。
幻讀有什么問題?
- 造成數據不一致的問題。尤其時binlog 格式為statement。先開始但后提交的事務會將數據覆蓋更新了
如何解決幻讀?
MVCC版本控制 + 間隙鎖。間隙鎖和間隙鎖不沖突,只和插入間隙記錄這一動作相沖突。
間隙鎖和行鎖合稱 next-key lock, 每個next-key lock 是前開后閉區間。
間隙鎖解決了幻讀,又造成了並發下降的問題
比如兩個事務都執行下面的語句
begin;
select * from t where id=9 for update;
insert inot values(9, 9, 9);
id=9這一行並不存在,因此會加上間隙鎖 (5, 10); 加間隙鎖之間並不沖突,當時兩個同時執行的事務執行insert 操作時又會被彼此加的間隙鎖阻塞,不得已,MySQL檢測了死鎖,讓其中一個事務報錯返回了。其實這樣降低了並發度,因此一些互聯網公司將事務隔離級別設置為RC並把binlog格式設置為Row。