什么是事務的隔離級別
事務的隔離級別秩贰,老生常談的問題了赔蒲,指多個事務并發(fā)執(zhí)行的時候相互之間不受到彼此的干擾矮燎,根據(jù)隔離程度對隔離性有會分類毡证。在具體介紹事務隔離性前有必要介紹幾個名詞說明數(shù)據(jù)庫并發(fā)操作存在的問題。
臟讀
事務可以讀取未提交的數(shù)據(jù)恢筝,就被稱為臟讀哀卫。 -------《高性能MySQL》
從定義來看,這個很好理解撬槽,舉個例子來說:假如有兩個事務A
和B
同時更新一個數(shù)據(jù)c=1
此改,事務A
執(zhí)行select
語句獲取到c=1
,然后事務A
將數(shù)據(jù)更改為c=2
但是沒有提交事務侄柔。這時候事務B
執(zhí)行select
發(fā)現(xiàn)此時的數(shù)據(jù)為c=2
共啃,這樣就產生了臟讀。
不可重復讀
事務在提交前可以看到其他事務已經(jīng)提交的數(shù)據(jù)暂题,導致兩次讀取出現(xiàn)不一樣的結果移剪,我們稱之為不可重復讀
同樣舉例來說明這種數(shù)據(jù)出現(xiàn)的情況:兩個事務A
和B
,事務A
執(zhí)行select
操作查詢出數(shù)據(jù)d=1
薪者,此時事務B
將此數(shù)據(jù)更改為d=2
并提交了事務纵苛,此時事務A
再執(zhí)行select
操作時,發(fā)現(xiàn)數(shù)據(jù)d=2
和上一次查詢的結果不一樣啸胧,這就導致了數(shù)據(jù)的不可重復讀赶站。
幻讀
所謂幻讀幔虏,是指當某個事務在讀取某個范圍內的記錄時纺念,另外一個事務又在改范圍內插入了新的記錄,當之前的事務再次讀取該范圍的記錄時想括,會產生幻行陷谱。 --《高性能MySQL》
上面的定義是我們理解中的定義,大部分人都是這么理解幻讀,然而幻讀真的是如此的嗎烟逊?后面介紹隔離性的時候我們會在實際操作中驗證這點渣窜。
事務的隔離級別
Read Uncommited
未提交讀隔離級別,就是指一個事務中可以讀取其他事務未提交的數(shù)據(jù)宪躯,這個級別會導致臟讀乔宿。下面在我本機安裝的mysql
中驗證這一點;
mysql
的默認隔離級別是Repeatable Read
访雪,如下圖所示:
下面我們把隔離級別改為Read Uncommited:
下面驗證此隔離級別下會出現(xiàn)的臟讀情況详瑞,打開兩個終端
終端一:開啟事務,查詢
test
表中的數(shù)據(jù)臣缀,結果如下終端二:開啟事務坝橡,往test
表中插入數(shù)據(jù),但是不提交事務精置,結果如下
終端一:終端二插入數(shù)據(jù)以后往在終端一中執(zhí)行同樣的查詢語句计寇,結果如下
然后將終端二中的事務回滾,此時在終端一中的事務中查詢數(shù)據(jù)脂倦,發(fā)現(xiàn)剛才插入的數(shù)據(jù)又消失了
終端二:
終端一:
從上圖發(fā)現(xiàn)番宁,在終端二中的事務沒有提交的情況下,終端一中的事務就能夠讀取到插入的數(shù)據(jù)赖阻,所以在 read-uncommitted
隔離條件下就會產生臟讀的情況贝淤。這個隔離級別是最低的隔離級別,上面所說的臟讀政供、不可重復讀和幻讀等情況都會出現(xiàn)播聪,所以一般來說不使用此隔離級別。
Read Committed
提交讀隔離級別布隔,一個事務開始時离陶,只能讀取到已經(jīng)提交的事務所做的修改。這個隔離級別會出現(xiàn)不可重復讀的情況
修改數(shù)據(jù)庫的事務隔離級別為Read Committed
:
終端一:
終端二:
終端一:
從上面兩個終端的截圖發(fā)現(xiàn)衅檀,終端二中的事務在沒有提交事務的情況下招刨,修改的數(shù)據(jù)在終端一中是查詢不到的,提交事務哀军,再查看結果
終端二:
終端一:
從上面結果看出沉眶,終端二中的事務提交以后,在終端一中可以查詢出結果杉适。
該隔離級別下面會出現(xiàn)不可重復讀和幻讀的情況谎倔,但是不會出現(xiàn)臟讀的情況,
oracle
的默認隔離級別就是提交讀的隔離級別猿推。
Repeatable Read
可重復讀隔離級別片习,保證同一個事務在多次讀取同樣的結果中是一致的捌肴。
修改隔離級別
我們按照《高性能MySQL》上的說法做一個實驗,看看是否會出現(xiàn)幻讀的情況:
終端一:
終端二:
終端一:
從上面來看藕咏,并沒有出現(xiàn)幻讀的情況状知,終端一中的數(shù)據(jù)集并沒有發(fā)生改變。其實幻讀不能理解成讀-讀的過程孽查,而是應該理解為讀-寫的過程饥悴,事務在插入事先檢測不存在的記錄時,驚奇的發(fā)現(xiàn)這些數(shù)據(jù)已經(jīng)存在了盲再,之前監(jiān)測到的數(shù)據(jù)中多了一行铺坞,像產生幻覺一樣。怎么理解上面那句話呢洲胖,下面這個例子就能很好的解釋這一點:
事務一:
執(zhí)行sql:
select * from test where id = 3;
執(zhí)行結果為null
济榨,證明沒有主鍵 id=3
的這行數(shù)據(jù)
事務二:
執(zhí)行sql:
insert into test(id,num,date) values(3,3,now());
然后提交事務二
事務一:
執(zhí)行sql:
insert into test(id,num,date) values(3,3,now());
執(zhí)行此 sql
時發(fā)現(xiàn)報錯,顯示已經(jīng)有id=3
數(shù)據(jù)绿映,就像產生幻覺擒滑,明明是沒有數(shù)據(jù),為什么突然出現(xiàn)這行數(shù)據(jù)呢2嫦摇Xひ弧!
Serializable
可串行化隔離級別淹冰,強制事務串行執(zhí)行库车,這種隔離級別在實際使用中很少用,所以不做過多的介紹樱拴。