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