MySQL幻讀是指在一個(gè)事務(wù)中,當(dāng)多次讀取同一個(gè)表時(shí),意外地出現(xiàn)了新的行。這可能是由于另一個(gè)事務(wù)已經(jīng)向表中插入了新的行,導(dǎo)致當(dāng)前事務(wù)重新讀取該表并得到了不同的結(jié)果。
事務(wù)1: START TRANSACTION; SELECT * FROM table WHERE column = 1; -- 這里得到 3 行 事務(wù)2: START TRANSACTION; INSERT INTO table(column) VALUES(1); 事務(wù)1: SELECT * FROM table WHERE column = 1; -- 這里得到 4 行,因?yàn)槭聞?wù)2 插入了一行,導(dǎo)致了幻讀
為了解決幻讀問題,MySQL提供了兩種機(jī)制:鎖定和多版本并發(fā)控制(MVCC)。
鎖定是通過對表或行進(jìn)行鎖定來防止多個(gè)事務(wù)同時(shí)對同一個(gè)表進(jìn)行操作。鎖定有兩種類型:共享鎖和排他鎖。共享鎖允許讀取操作同時(shí)進(jìn)行,但不允許寫入操作;排他鎖允許寫入操作進(jìn)行,但不允許讀取或?qū)懭氩僮鳌?/p>
MVCC是一種機(jī)制,用于在多個(gè)事務(wù)共享相同數(shù)據(jù)的情況下,控制并發(fā)操作并提高數(shù)據(jù)庫的性能。MVCC與鎖定的不同之處在于,它通常不鎖定表或行,而是根據(jù)事務(wù)的時(shí)間戳來決定哪個(gè)事務(wù)可以訪問某個(gè)數(shù)據(jù)版本。
事務(wù)1(時(shí)間戳為T1): START TRANSACTION; SELECT * FROM table WHERE column = 1; -- 這里得到 3 行,根據(jù)當(dāng)前的時(shí)間戳讀取數(shù)據(jù) 事務(wù)2(時(shí)間戳為T2): START TRANSACTION; INSERT INTO table(column) VALUES(1); 事務(wù)1: SELECT * FROM table WHERE column = 1; -- 這里仍然得到 3 行,因?yàn)門1 早于T2,所以不會(huì)看到新增的行
使用MVCC可以避免大部分的鎖定沖突,提高數(shù)據(jù)庫的性能和并發(fā)度。在MySQL中,MVCC通過InnoDB存儲(chǔ)引擎來實(shí)現(xiàn)。
上一篇mysql幻讀怎么處理
下一篇mysql并行配置不正確