サマリー:mysql實(shí)現(xiàn)了四種隔離級(jí)別Read Uncommitted(未提交讀) 在該隔離級(jí)別,所有事務(wù)都可以看到其他未提交事務(wù)的執(zhí)行結(jié)果。本隔離級(jí)別很少用于實(shí)際應(yīng)用,因?yàn)樗男阅芤膊槐绕渌?jí)別好多少。讀取未提交的數(shù)據(jù),也被稱之為臟讀(Dirty Read)。 Read Committed(不可重復(fù)讀)  
mysql實(shí)現(xiàn)了四種隔離級(jí)別
Read Uncommitted(未提交讀)
在該隔離級(jí)別,所有事務(wù)都可以看到其他未提交事務(wù)的執(zhí)行結(jié)果。本隔離級(jí)別很少用于實(shí)際應(yīng)用,因?yàn)樗男阅芤膊槐绕渌?jí)別好多少。讀取未提交的數(shù)據(jù),也被稱之為臟讀(Dirty Read)。
Read Committed(不可重復(fù)讀)
這是大多數(shù)數(shù)據(jù)庫系統(tǒng)的默認(rèn)隔離級(jí)別(但不是MySQL默認(rèn)的)。它滿足了隔離的簡(jiǎn)單定義:一個(gè)事務(wù)只能看見已經(jīng)提交事務(wù)所做的改變。這種隔離級(jí)別 也支持所謂的不可重復(fù)讀(Nonrepeatable Read),因?yàn)橥皇聞?wù)的其他實(shí)例在該實(shí)例處理其間可能會(huì)有新的commit,所以同一select可能返回不同結(jié)果。(一個(gè)事物多次讀取的結(jié)果可能不一樣)。也叫提交讀。
Repeatable Read(可重復(fù)讀)
這是MySQL的默認(rèn)事務(wù)隔離級(jí)別,它確保同一事務(wù)的多個(gè)實(shí)例在并發(fā)讀取數(shù)據(jù)時(shí),會(huì)看到同樣的數(shù)據(jù)行(mysql用快照解決該問題)。不過理論上,這會(huì)導(dǎo)致另一個(gè)棘手的問題:幻讀 (Phantom Read)。簡(jiǎn)單的說,幻讀指當(dāng)用戶讀取某一范圍的數(shù)據(jù)行時(shí),另一個(gè)事務(wù)又在該范圍內(nèi)插入了新行,當(dāng)用戶再讀取該范圍的數(shù)據(jù)行時(shí),會(huì)發(fā)現(xiàn)有新的“幻影” 行(mysql用間隙鎖解決該問題)。InnoDB和Falcon存儲(chǔ)引擎通過多版本并發(fā)控制(MVCC,Multiversion Concurrency Control)機(jī)制解決了該問題。(一個(gè)事物多次讀取的結(jié)果一樣)。
Serializable(可串行化)
這是最高的隔離級(jí)別,它通過強(qiáng)制事務(wù)排序,使之不可能相互沖突,從而解決幻讀問題。簡(jiǎn)言之,它是在每個(gè)讀的數(shù)據(jù)行上加上共享鎖。在這個(gè)級(jí)別,可能導(dǎo)致大量的超時(shí)現(xiàn)象和鎖競(jìng)爭(zhēng)。
-------------------------------------------------------------------------------------------------------------------------------------------------
Repeatable Read隔離級(jí)別衍生問題總結(jié)
幻讀:一個(gè)事務(wù)在操作過程中!有別的事務(wù)對(duì)此數(shù)據(jù)集進(jìn)行了修改并提交,但這些操作第一個(gè)事務(wù)讀不到,等到這個(gè)事務(wù)提交的時(shí)候,便有可能引起明明插入的數(shù)據(jù)沒有查詢到,但卻出現(xiàn)插入重復(fù)的錯(cuò)誤!
不可重復(fù)讀與幻讀的區(qū)別:
不可重復(fù)讀是能讀到其它事務(wù)已經(jīng)提交的數(shù)據(jù),幻讀是讀不到其它事務(wù)已提交的數(shù)據(jù)!
間隙鎖:間隙鎖主要用來防止幻讀,用在repeatable-read隔離級(jí)別下,指的是當(dāng)對(duì)數(shù)據(jù)進(jìn)行條件,范圍檢索時(shí),對(duì)其范圍內(nèi)也許并存在的值進(jìn)行加鎖!
---------------------------------------
比如where id <8 lock in share mode,則對(duì)8以下的值都加間隙鎖,
select max(id) ........lock in share mode,則會(huì)對(duì)max(id)以上的并不存在值加間隙鎖!
select * from e where id=20 lock in share mode 則只會(huì)對(duì)id=20加鎖?。ù藭r(shí)可能只是普通的共享鎖了)
select * from e lock in share mode; 則對(duì)整個(gè)e加上間隙表鎖!
幻讀案例:有個(gè)表(id字段為唯一約束)每次插入前需查詢這字段的最大值,然后再取最大值+1插入!
事務(wù)1: 事務(wù)2:
select max(id) from e; insert into e values (11)
10 commit;
insert into e values (11)
commit;
ERROR 1062 (23000): Duplicate entry ‘11‘ for key ‘id‘
在上述事務(wù)1中明明查詢最大值為10,但插入最大值+1的時(shí)候卻報(bào)錯(cuò)!
解決方案:利用mysql間隙鎖
事務(wù)1: 事務(wù)2:
select max(id) from e lock in share mode;
(此時(shí)會(huì)對(duì)id為10以上的所有不存在的值加間隙鎖)
10 insert into e values (11);
insert into e values (11) commit; 此時(shí)提交會(huì)一處于等待狀態(tài),
commit;
---------------------------------------
幻讀問題解決,但是上面的例子中,會(huì)導(dǎo)致上面的插入語句等待。