要說幻讀揍诽,?先要了解MVCC,MVCC叫做多版本并發(fā)控制,實際上就是保存了數(shù)據(jù)在某個時間節(jié)點的快照暑脆。
我們每?數(shù)實際上隱藏了兩列渠啤,創(chuàng)建時間版本號,過期(刪除)時間版本號添吗,每開始?個新的事務沥曹,版本號都會?動遞增。
還是拿user表舉例?根资,假設我們插?兩條數(shù)據(jù)架专,它們實際上應該?這樣
這時候假設?明去執(zhí)?查詢,此時current_version=3
select * from user where id<=3;
同時玄帕,?紅在這時候開啟事務去修改id=1的記錄部脚,current_version=4
update user set name='張三三' where id=1;
執(zhí)?成功后的結(jié)果是這樣的
如果這時候還有??在刪除id=2的數(shù)據(jù),current_version=5裤纹,執(zhí)?后結(jié)果是這樣的委刘。
由于MVCC的原理是查找創(chuàng)建版本?于或等于當前事務版本,刪除版本為空或者?于當前事務版本鹰椒,?明的真實的查詢應該是這樣
select * from user where id<=3 and create_version<=3 and (delete_version>3 or delete_version is null);
所以?明最后查詢到的id=1的名字還是'張三'锡移,并且id=2的記錄也能查詢到。這樣做是為了保證事務讀取的數(shù)據(jù)是在事務開始前就已經(jīng)存在的漆际,要么是事務??插?或者修改的淆珊。
明?MVCC原理,我們來說什么是幻讀就簡單多了奸汇。舉?個常?的場景施符,?戶注冊時,我們先查詢?戶名是否存在擂找,不存在就插?戳吝,假定?戶名是唯?索引。
1. ?明開啟事務current_version=6查詢名字為'王五'的記錄贯涎,發(fā)現(xiàn)不存在听哭。
2. ?紅開啟事務current_version=7插??條數(shù)據(jù),結(jié)果是這樣:
3. ?明執(zhí)?插?名字'王五'的記錄塘雳,發(fā)現(xiàn)唯?索引沖突陆盘,?法插?,這就是幻讀败明。