MySQL的ACID屬性中的“I”代表不可重復(fù)讀(Non-repeatable Read)。這是指一個(gè)事務(wù)在執(zhí)行過(guò)程中,當(dāng)兩次讀取同一數(shù)據(jù)行時(shí),可能會(huì)得到不同的結(jié)果。例如,一個(gè)事務(wù)在執(zhí)行過(guò)程中曾經(jīng)讀取過(guò)一條數(shù)據(jù),但在該事務(wù)結(jié)束之前,另一個(gè)事務(wù)更新了該數(shù)據(jù)行。如果第一個(gè)事務(wù)再次讀取同一行數(shù)據(jù),就會(huì)發(fā)現(xiàn)數(shù)據(jù)發(fā)生了變化,這個(gè)現(xiàn)象就是不可重復(fù)讀。
例如,假設(shè)有一個(gè)用戶表:users(id, name, age)。在事務(wù)A中,執(zhí)行以下操作: BEGIN; SELECT age FROM users WHERE name='John'; 此時(shí),數(shù)據(jù)庫(kù)返回 age=30。但是在事務(wù)A還沒(méi)有提交之前,事務(wù)B進(jìn)行了以下操作: BEGIN; UPDATE users SET age=35 WHERE name='John'; COMMIT; 現(xiàn)在,如果事務(wù)A再次查詢 users 表中 name 為 John 的用戶的 age 時(shí),得到的結(jié)果是35,而不是之前的30。這就是不可重復(fù)讀的問(wèn)題。
為了解決不可重復(fù)讀的問(wèn)題,MySQL提供了幾種隔離級(jí)別(Isolation Level),可以通過(guò)設(shè)置事務(wù)隔離級(jí)別來(lái)避免不可重復(fù)讀的問(wèn)題。MySQL默認(rèn)的隔離級(jí)別是“可重復(fù)讀(Repeatable Read)”,即同一事務(wù)中多次讀取同一行數(shù)據(jù)時(shí),返回的結(jié)果都是一致的。但是,這種隔離級(jí)別也會(huì)導(dǎo)致另一個(gè)問(wèn)題:幻讀(Phantom Read)。
總之,不可重復(fù)讀是數(shù)據(jù)庫(kù)中常見(jiàn)的問(wèn)題之一,但是可以通過(guò)設(shè)置適當(dāng)?shù)氖聞?wù)隔離級(jí)別來(lái)避免這個(gè)問(wèn)題。