隨著互聯(lián)網(wǎng)和大數(shù)據(jù)的發(fā)展,數(shù)據(jù)庫逐漸成為數(shù)據(jù)持久化存儲的標準之一。而在眾多的數(shù)據(jù)庫中,MySQL絕對是其中的佼佼者之一。但是,為了提高多線程并發(fā)處理能力,MySQL也提供了多種隔離級別,其中包括:讀未提交、讀已提交、可重復讀和串行化等。然而,這些不同的隔離級別卻會帶來一種常見的問題——幻讀。
幻讀是指同一事務(wù)中兩次查詢同一范圍的結(jié)果集時,第二次查詢會發(fā)現(xiàn)多了或者少了記錄。簡單點說幻讀就是InnoDB中在可重復讀隔離級別下的一種現(xiàn)象。如圖所示:
Transaction A: SELECT * FROM table WHERE column=1; Transaction B: INSERT INTO table VALUES (1, 'name1', 18); Transaction A: SELECT * FROM table WHERE column=1;
在Transaction A執(zhí)行完成前,Transaction B插入了一個新記錄,這時Transaction A在SELECT時,會出現(xiàn)剛剛插入的行,這就是幻讀。
為了避免幻讀,MySQL提供的可重復讀隔離級別是基于mvcc實現(xiàn)的。在可重復讀隔離級別下,MySQL通過使用next-key鎖和gap鎖來保證查詢的所有記錄都處于被訪問的事務(wù)的一致視圖中。當一個事務(wù)需要讀取一行數(shù)據(jù)時,MySQL會創(chuàng)建一個“當前讀”鎖或共享讀鎖。如果使用了范圍操作符,則MySQL還會創(chuàng)建一個“間隙鎖”或“next-key”鎖。
在實際應用中應該根據(jù)業(yè)務(wù)特點來選擇合適的隔離級別,以避免幻讀的產(chǎn)生。
上一篇css清浮動并保留效果
下一篇mysql忘記賬號密碼了