在數(shù)據(jù)操作的過程中可能出現(xiàn)的情況
1、臟讀
臟讀是指在一個(gè)事務(wù)處理過程里讀取了另一個(gè)未提交的事務(wù)中的數(shù)據(jù)哀澈。
當(dāng)一個(gè)事務(wù)正在多次修改某個(gè)數(shù)據(jù),而在這個(gè)事務(wù)中這多次的修改都還未提交,這時(shí)一個(gè)并發(fā)的事務(wù)來訪問該數(shù)據(jù)拔稳,就會(huì)造成兩個(gè)事務(wù)得到的數(shù)據(jù)不一致。
2锹雏、不可重復(fù)讀
不可重復(fù)讀是指在對于數(shù)據(jù)庫中的某個(gè)數(shù)據(jù)巴比,一個(gè)事務(wù)范圍內(nèi)多次查詢卻返回了不同的數(shù)據(jù)值,這是由于在查詢間隔,被另一個(gè)事務(wù)修改并提交了轻绞。
例如事務(wù)T1在讀取某一數(shù)據(jù)采记,而事務(wù)T2立馬修改了這個(gè)數(shù)據(jù)并且提交事務(wù)給數(shù)據(jù)庫,事務(wù)T1再次讀取該數(shù)據(jù)就得到了不同的結(jié)果政勃,發(fā)送了不可重復(fù)讀唧龄。
不可重復(fù)讀和臟讀的區(qū)別是,臟讀是某一事務(wù)讀取了另一個(gè)事務(wù)未提交的臟數(shù)據(jù)奸远,而不可重復(fù)讀則是讀取了前一事務(wù)提交的數(shù)據(jù)既棺。
在某些情況下,不可重復(fù)讀并不是問題懒叛,比如我們多次查詢某個(gè)數(shù)據(jù)當(dāng)然以最后查詢得到的結(jié)果為主丸冕。但在另一些情況下就有可能發(fā)生問題,例如對于同一個(gè)數(shù)據(jù)A和B依次查詢就可能不同薛窥,A和B就可能打起來了……
3胖烛、虛讀(幻讀)
事務(wù)T1讀取某一數(shù)據(jù)后,事務(wù)T2對其做了修改诅迷,當(dāng)事務(wù)T1再次讀該數(shù)據(jù)時(shí)得到與前一次不同的值佩番。
事務(wù)在操作過程中進(jìn)行兩次查詢,第二次查詢的結(jié)果包含了第一次查詢中未出現(xiàn)的數(shù)據(jù)或者缺少了第一次查詢中出現(xiàn)的數(shù)據(jù)(這里并不要求兩次查詢的SQL語句相同)竟贯。這是因?yàn)樵趦纱尾樵冞^程中有另外一個(gè)事務(wù)插入數(shù)據(jù)造成的答捕。
數(shù)據(jù)庫事務(wù)的隔離級別
1、Read uncommitted(未授權(quán)讀取屑那、讀未提交)
最低級別拱镐,任何情況都無法保證。
如果一個(gè)事務(wù)已經(jīng)開始寫數(shù)據(jù)持际,則另外一個(gè)事務(wù)則不允許同時(shí)進(jìn)行寫操作沃琅,但允許其他事務(wù)讀此行數(shù)據(jù)。該隔離級別可以通過“排他寫鎖”實(shí)現(xiàn)蜘欲。避免了更新丟失益眉,卻可能出現(xiàn)臟讀。也就是說事務(wù)B讀取到了事務(wù)A未提交的數(shù)據(jù)姥份。
2郭脂、Read committed(授權(quán)讀取、讀提交)
可避免臟讀的發(fā)生澈歉,但是卻可能出現(xiàn)不可重復(fù)讀展鸡。
讀取數(shù)據(jù)的事務(wù)允許其他事務(wù)繼續(xù)訪問該行數(shù)據(jù),但是未提交的寫事務(wù)將會(huì)禁止其他事務(wù)訪問該行埃难。
事務(wù)A事先讀取了數(shù)據(jù)莹弊,事務(wù)B緊接了更新了數(shù)據(jù)涤久,并提交了事務(wù),而事務(wù)A再次讀取該數(shù)據(jù)時(shí)忍弛,數(shù)據(jù)已經(jīng)發(fā)生了改變响迂。
3、Repeatable read(可重復(fù)讀认妇巍)
可避免臟讀蔗彤、不可重復(fù)讀的發(fā)生,但是有時(shí)可能出現(xiàn)幻讀惠昔。這可以通過“共享讀鎖”和“排他寫鎖”實(shí)現(xiàn)幕与。
讀取數(shù)據(jù)的事務(wù)將會(huì)禁止寫事務(wù)(但允許讀事務(wù)),寫事務(wù)則禁止任何其他事務(wù)镇防。
4啦鸣、Serializable(序列化)
可避免臟讀、不可重復(fù)讀来氧、幻讀的發(fā)生诫给。
提供嚴(yán)格的事務(wù)隔離。它要求事務(wù)序列化執(zhí)行啦扬,事務(wù)只能一個(gè)接著一個(gè)地執(zhí)行中狂,但不能并發(fā)執(zhí)行。如果僅僅通過“行級鎖”是無法實(shí)現(xiàn)事務(wù)序列化的扑毡,必須通過其他機(jī)制保證新插入的數(shù)據(jù)不會(huì)被剛執(zhí)行查詢操作的事務(wù)訪問到胃榕。
序列化是最高的事務(wù)隔離級別,同時(shí)代價(jià)也花費(fèi)最高瞄摊,性能很低勋又,一般很少使用,在該級別下换帜,事務(wù)順序執(zhí)行楔壤。
總結(jié)
隔離級別越高,越能保證數(shù)據(jù)的完整性和一致性惯驼,但是對并發(fā)性能的影響也越大蹲嚣。對于多數(shù)應(yīng)用程序,可以優(yōu)先考慮把數(shù)據(jù)庫系統(tǒng)的隔離級別設(shè)為Read Committed祟牲。它能夠避免臟讀取隙畜,而且具有較好的并發(fā)性能。盡管它會(huì)導(dǎo)致不可重復(fù)讀说贝、幻讀和第二類丟失更新這些并發(fā)問題禾蚕,在可能出現(xiàn)這類問題的個(gè)別場合,可以由應(yīng)用程序采用悲觀鎖或樂觀鎖來控制狂丝。
大多數(shù)數(shù)據(jù)庫的默認(rèn)級別就是Read committed换淆,比如SQL Server , Oracle。
MySQL的默認(rèn)隔離級別就是Repeatable read几颜。
例子1:MySQL中查看事務(wù)的隔離級別
SELECT @@TX_ISOLATION;
例子2:MySQL中設(shè)置事務(wù)隔離級別
SET [GLOBAL | SESSION] TRANSACTION ISOLATION LEVEL 隔離級別名稱;
或者
SET TX_ISOLATION = '隔離級別名稱';