在了解臟讀,不可重復(fù)度,幻讀之前,首先要明白這三種情況的出現(xiàn)都是和數(shù)據(jù)庫(kù)并發(fā)事務(wù)有關(guān)聯(lián)的,如果所有的讀寫都按照隊(duì)列的形式進(jìn)行,就不會(huì)出現(xiàn)問(wèn)題。 名詞解析和解決方案臟讀 臟讀又稱無(wú)效數(shù)據(jù)讀出(讀出了臟數(shù)據(jù))。一個(gè)事務(wù)讀取另外一個(gè)事務(wù)還沒(méi)有提交的數(shù)據(jù)叫臟讀。 例如:事務(wù)T1修改了某個(gè)表中的一行數(shù)據(jù),但是還沒(méi)有提交,這時(shí)候事務(wù)T2讀取了被事務(wù)T1修改后的數(shù)據(jù),之后事務(wù)T1因?yàn)槟撤N原因回滾(Rollback)了,那么事務(wù)T2讀取的數(shù)據(jù)就是臟的(無(wú)效的)。 解決辦法:把數(shù)據(jù)庫(kù)的事務(wù)隔離級(jí)別調(diào)整到READ_COMMITTED(讀提交/不可重復(fù)讀) 不可重復(fù)讀 不可重復(fù)讀是指在同一個(gè)事務(wù)內(nèi),兩次相同的查詢返回了不同的結(jié)果。 例如:事務(wù)T1會(huì)讀取兩次數(shù)據(jù),在第一次讀取某一條數(shù)據(jù)后,事務(wù)T2修改了該數(shù)據(jù)并提交了事務(wù),T1此時(shí)再次讀取該數(shù)據(jù),兩次讀取便得到了不同的結(jié)果。 解決辦法:把數(shù)據(jù)庫(kù)的事務(wù)隔離級(jí)別調(diào)整到REPEATABLE_READ(可重復(fù)讀) 幻讀 幻讀也是指當(dāng)事務(wù)不獨(dú)立執(zhí)行時(shí),插入或者刪除另一個(gè)事務(wù)當(dāng)前影響的數(shù)據(jù)而發(fā)生的一種類似幻覺(jué)的現(xiàn)象。 例如:系統(tǒng)事務(wù)A將數(shù)據(jù)庫(kù)中所有數(shù)據(jù)都刪除的時(shí)候,但是事務(wù)B就在這個(gè)時(shí)候新插入了一條記錄,當(dāng)事務(wù)A刪除結(jié)束后發(fā)現(xiàn)還有一條數(shù)據(jù),就好像發(fā)生了幻覺(jué)一樣。這就叫幻讀。 解決辦法:把數(shù)據(jù)庫(kù)的事務(wù)隔離級(jí)別調(diào)整到SERIALIZABLE_READ(序列化執(zhí)行),或者數(shù)據(jù)庫(kù)使用者自己進(jìn)行加鎖來(lái)保證。 題外話:不可重復(fù)讀出現(xiàn)多是因?yàn)樾薷?;幻讀重點(diǎn)是新增、刪除。mysql中的REPEATABLE_READ模式引入了間隙鎖(GAP),解決了幻讀的問(wèn)題。不論是什么方式解決幻讀,都會(huì)付出一定代價(jià)的性能讓步。所以說(shuō)在業(yè)務(wù)需求和技術(shù)方案之間權(quán)衡也是技術(shù)人員最需要掌握得技能之一。 |
|