參考http://blog.csdn.net/fg2006/article/details/6937413
數(shù)據(jù)庫(kù)事務(wù)的隔離級(jí)別有4個(gè)耸彪,由低到高依次為Read uncommitted、Read committed唱较、Repeatable read召川、Serializable,這四個(gè)級(jí)別可以逐個(gè)解決臟讀西乖、不可重復(fù)讀坛增、幻讀這幾類(lèi)問(wèn)題收捣。
√: 可能出現(xiàn)????×: 不會(huì)出現(xiàn)
臟讀不可重復(fù)讀幻讀
Read uncommitted√√√
Read committed×√√
Repeatable read××√
Serializable×××
注意:我們討論隔離級(jí)別的場(chǎng)景庵楷,主要是在多個(gè)事務(wù)并發(fā)的情況下,因此咐蚯,接下來(lái)的講解都圍繞事務(wù)并發(fā)弄贿。
公司發(fā)工資了差凹,領(lǐng)導(dǎo)把5000元打到singo的賬號(hào)上侧馅,但是該事務(wù)并未提交呐萌,而singo正好去查看賬戶(hù)肺孤,發(fā)現(xiàn)工資已經(jīng)到賬,是5000元整小渊,非常高興顾腊。可是不幸的是梆惯,領(lǐng)導(dǎo)發(fā)現(xiàn)發(fā)給singo的工資金額不對(duì)垛吗,是2000元烁登,于是迅速回滾了事務(wù),修改金額后锨络,將事務(wù)提交羡儿,最后singo實(shí)際的工資只有2000元是钥,singo空歡喜一場(chǎng)悄泥。
出現(xiàn)上述情況,即我們所說(shuō)的臟讀厨相,兩個(gè)并發(fā)的事務(wù),“事務(wù)A:領(lǐng)導(dǎo)給singo發(fā)工資”领铐、“事務(wù)B:singo查詢(xún)工資賬戶(hù)”绪撵,事務(wù)B讀取了事務(wù)A尚未提交的數(shù)據(jù)音诈。
當(dāng)隔離級(jí)別設(shè)置為Read uncommitted時(shí),就可能出現(xiàn)臟讀褥傍,如何避免臟讀喇聊,請(qǐng)看下一個(gè)隔離級(jí)別誓篱。
singo拿著工資卡去消費(fèi),系統(tǒng)讀取到卡里確實(shí)有2000元锦募,而此時(shí)她的老婆也正好在網(wǎng)上轉(zhuǎn)賬糠亩,把singo工資卡的2000元轉(zhuǎn)到另一賬戶(hù)赎线,并在singo之前提交了事務(wù)糊饱,當(dāng)singo扣款時(shí)济似,系統(tǒng)檢查到singo的工資卡已經(jīng)沒(méi)有錢(qián)盏缤,扣款失敗,singo十分納悶台舱,明明卡里有錢(qián),為何......
出現(xiàn)上述情況竞惋,即我們所說(shuō)的不可重復(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)隔離級(jí)別設(shè)置為Read committed時(shí)废士,避免了臟讀官硝,但是可能會(huì)造成不可重復(fù)讀氢架。
大多數(shù)數(shù)據(jù)庫(kù)的默認(rèn)級(jí)別就是Read committed岖研,比如Sql Server , Oracle。如何解決不可重復(fù)讀這一問(wèn)題扇雕,請(qǐng)看下一個(gè)隔離級(jí)別镶奉。
當(dāng)隔離級(jí)別設(shè)置為Repeatable read時(shí)腮鞍,可以避免不可重復(fù)讀移国。當(dāng)singo拿著工資卡去消費(fèi)時(shí)迹缀,一旦系統(tǒng)開(kāi)始讀取工資卡信息(即事務(wù)開(kāi)始)祝懂,singo的老婆就不可能對(duì)該記錄進(jìn)行修改砚蓬,也就是singo的老婆不能在此時(shí)轉(zhuǎn)賬灰蛙。
雖然Repeatable read避免了不可重復(fù)讀摩梧,但還有可能出現(xiàn)幻讀仅父。
singo的老婆工作在銀行部門(mén)笙纤,她時(shí)常通過(guò)銀行內(nèi)部系統(tǒng)查看singo的信用卡消費(fèi)記錄粪糙。有一天,她正在查詢(xún)到singo當(dāng)月信用卡的總消費(fèi)金額(select sum(amount) from transaction where month = 本月)為80元轩触,而singo此時(shí)正好在外面胡吃海塞后在收銀臺(tái)買(mǎi)單脱柱,消費(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)了幻覺(jué)蹄胰,幻讀就這樣產(chǎn)生了裕寨。
注:Mysql的默認(rèn)隔離級(jí)別就是Repeatable read宾袜。
Serializable是最高的事務(wù)隔離級(jí)別,同時(shí)代價(jià)也花費(fèi)最高月培,性能很低杉畜,一般很少使用此叠,在該級(jí)別下猬错,事務(wù)順序執(zhí)行倦炒,不僅可以避免臟讀析校、不可重復(fù)讀,還避免了幻像讀吊奢。