本文系轉(zhuǎn)載狭瞎,原文地址:http://singo107.iteye.com/blog/1175084
數(shù)據(jù)庫事務(wù)的隔離級別有4個(gè),由低到高依次為Read uncommitted欢唾、Read committed且警、Repeatable read、Serializable礁遣,這四個(gè)級別可以逐個(gè)解決臟讀斑芜、不可重復(fù)讀、幻讀這幾類問題祟霍。
注意:我們討論隔離級別的場景杏头,主要是在多個(gè)事務(wù)并發(fā)的情況下,因此沸呐,接下來的講解都圍繞事務(wù)并發(fā)醇王。
Read uncommitted 讀未提交#
公司發(fā)工資了,領(lǐng)導(dǎo)把5000元打到singo的賬號上崭添,但是該事務(wù)并未提交寓娩,而singo正好去查看賬戶,發(fā)現(xiàn)工資已經(jīng)到賬呼渣,是5000元整棘伴,非常高興∑ㄖ茫可是不幸的是排嫌,領(lǐng)導(dǎo)發(fā)現(xiàn)發(fā)給singo的工資金額不對,是2000元缰犁,于是迅速回滾了事務(wù),修改金額后怖糊,將事務(wù)提交帅容,最后singo實(shí)際的工資只有2000元,singo空歡喜一場伍伤。
出現(xiàn)上述情況并徘,即我們所說的臟讀,兩個(gè)并發(fā)的事務(wù)扰魂,“事務(wù)A:領(lǐng)導(dǎo)給singo發(fā)工資”麦乞、“事務(wù)B:singo查詢工資賬戶”,事務(wù)B讀取了事務(wù)A尚未提交的數(shù)據(jù)劝评。
當(dāng)隔離級別設(shè)置為Read uncommitted時(shí)姐直,就可能出現(xiàn)臟讀,如何避免臟讀蒋畜,請看下一個(gè)隔離級別声畏。
Read committed 讀提交#
singo拿著工資卡去消費(fèi),系統(tǒng)讀取到卡里確實(shí)有2000元,而此時(shí)她的老婆也正好在網(wǎng)上轉(zhuǎn)賬插龄,把singo工資卡的2000元轉(zhuǎn)到另一賬戶愿棋,并在singo之前提交了事務(wù),當(dāng)singo扣款時(shí)均牢,系統(tǒng)檢查到singo的工資卡已經(jīng)沒有錢糠雨,扣款失敗,singo十分納悶徘跪,明明卡里有錢甘邀,為何......
出現(xiàn)上述情況,即我們所說的不可重復(fù)讀真椿,兩個(gè)并發(fā)的事務(wù)鹃答,“事務(wù)A:singo消費(fèi)”、“事務(wù)B:singo的老婆網(wǎng)上轉(zhuǎn)賬”突硝,事務(wù)A事先讀取了數(shù)據(jù)测摔,事務(wù)B緊接了更新了數(shù)據(jù),并提交了事務(wù)解恰,而事務(wù)A再次讀取該數(shù)據(jù)時(shí)锋八,數(shù)據(jù)已經(jīng)發(fā)生了改變。
當(dāng)隔離級別設(shè)置為Read committed時(shí)护盈,避免了臟讀挟纱,但是可能會造成不可重復(fù)讀。
大多數(shù)數(shù)據(jù)庫的默認(rèn)級別就是Read committed腐宋,比如Sql Server , Oracle紊服。如何解決不可重復(fù)讀這一問題,請看下一個(gè)隔離級別胸竞。
Repeatable read 重復(fù)讀#
當(dāng)隔離級別設(shè)置為Repeatable read時(shí)欺嗤,可以避免不可重復(fù)讀。
當(dāng)singo拿著工資卡去消費(fèi)時(shí)卫枝,一旦系統(tǒng)開始讀取工資卡信息(即事務(wù)開始)煎饼,singo的老婆就不可能對該記錄進(jìn)行修改,也就是singo的老婆不能在此時(shí)轉(zhuǎn)賬校赤。
雖然Repeatable read避免了不可重復(fù)讀吆玖,但還有可能出現(xiàn)幻讀。
singo的老婆工作在銀行部門马篮,她時(shí)常通過銀行內(nèi)部系統(tǒng)查看singo的信用卡消費(fèi)記錄沾乘。有一天,她正在查詢到singo當(dāng)月信用卡的總消費(fèi)金額(select sum(amount) from transaction where month = 本月)為80元积蔚,而singo此時(shí)正好在外面胡吃海塞后在收銀臺買單意鲸,消費(fèi)1000元,即新增了一條1000元的消費(fèi)記錄(insert transaction ... ),并提交了事務(wù)怎顾,隨后singo的老婆將singo當(dāng)月信用卡消費(fèi)的明細(xì)打印到A4紙上读慎,卻發(fā)現(xiàn)消費(fèi)總額為1080元,singo的老婆很詫異槐雾,以為出現(xiàn)了幻覺夭委,幻讀就這樣產(chǎn)生了。
注:MySQL的默認(rèn)隔離級別就是Repeatable read募强。
Serializable 序列化#
Serializable是最高的事務(wù)隔離級別株灸,同時(shí)代價(jià)也花費(fèi)最高,性能很低擎值,一般很少使用慌烧,在該級別下,事務(wù)順序執(zhí)行鸠儿,不僅可以避免臟讀屹蚊、不可重復(fù)讀,還避免了幻像讀进每。