前言
在這里記錄一下一個(gè)博客,覺(jué)得寫的很好 http://hedengcheng.com/?p=771 恬砂,
概念
快照讀
??讀取的是記錄數(shù)據(jù)的可見(jiàn)版本(可能是過(guò)期的數(shù)據(jù))峦剔,不用加鎖
當(dāng)前讀
??讀取的是記錄數(shù)據(jù)的最新版本霹陡,并且當(dāng)前讀返回的記錄都會(huì)加上鎖皆尔,保證其他事務(wù)不會(huì)再并發(fā)的修改這條記錄
??概念說(shuō)的比較虛姚建,也不好理解矫俺,接著舉一個(gè)例子吧,假設(shè)你開(kāi)啟了兩個(gè)事務(wù)掸冤,分別是A和B厘托,這里有個(gè)張表,user表稿湿,里面有四條數(shù)據(jù)
1铅匹、select快照讀(照片)
??當(dāng)你執(zhí)行select *之后,在A與B事務(wù)中都會(huì)返回4條一樣的數(shù)據(jù)饺藤,這是不用想的包斑,當(dāng)執(zhí)行select的時(shí)候,innodb默認(rèn)會(huì)執(zhí)行快照讀涕俗,相當(dāng)于就是給你目前的狀態(tài)找了一張照片罗丰,以后執(zhí)行select 的時(shí)候就會(huì)返回當(dāng)前照片里面的數(shù)據(jù),當(dāng)其他事務(wù)提交了也對(duì)你不造成影響再姑,和你沒(méi)關(guān)系萌抵,這就實(shí)現(xiàn)了可重復(fù)讀了,那這個(gè)照片是什么時(shí)候生成的呢元镀?不是開(kāi)啟事務(wù)的時(shí)候绍填,是當(dāng)你第一次執(zhí)行select的時(shí)候,也就是說(shuō)栖疑,當(dāng)A開(kāi)啟了事務(wù)讨永,然后沒(méi)有執(zhí)行任何操作,這時(shí)候B insert了一條數(shù)據(jù)然后commit,這時(shí)候A執(zhí)行 select蔽挠,那么返回的數(shù)據(jù)中就會(huì)有B添加的那條數(shù)據(jù)......之后無(wú)論再有其他事務(wù)commit都沒(méi)有關(guān)系住闯,因?yàn)檎掌呀?jīng)生成了,而且不會(huì)再生成了澳淑,以后都會(huì)參考這張照片比原。
2、update杠巡、insert量窘、delete 當(dāng)前讀
??當(dāng)你執(zhí)行這幾個(gè)操作的時(shí)候默認(rèn)會(huì)執(zhí)行當(dāng)前讀,也就是會(huì)讀取最新的記錄氢拥,也就是別的事務(wù)提交的數(shù)據(jù)你也可以看到蚌铜,這樣很好理解啊锨侯,假設(shè)你要update一個(gè)記錄,另一個(gè)事務(wù)已經(jīng)delete這條數(shù)據(jù)并且commit了冬殃,這樣不是會(huì)產(chǎn)生沖突嗎囚痴,所以你update的時(shí)候肯定要知道最新的信息啊。
??我在這里介紹一下update的過(guò)程吧审葬,首先會(huì)執(zhí)行當(dāng)前讀深滚,然后把返回的數(shù)據(jù)加鎖,之后執(zhí)行update涣觉。加鎖是防止別的事務(wù)在這個(gè)時(shí)候?qū)@條記錄做什么痴荐,默認(rèn)加的是排他鎖,也就是你讀都不可以官册,這樣就可以保證數(shù)據(jù)不會(huì)出錯(cuò)了生兆。但注意一點(diǎn),就算你這里加了寫鎖膝宁,別的事務(wù)也還是能訪問(wèn)的鸦难,是不是很奇怪?數(shù)據(jù)庫(kù)采取了一致性非鎖定讀昆汹,別的事務(wù)會(huì)去讀取一個(gè)快照數(shù)據(jù)明刷。
??innodb默認(rèn)隔離級(jí)別是RR, 是通過(guò)MVVC來(lái)實(shí)現(xiàn)了满粗,讀方式有兩種辈末,執(zhí)行select的時(shí)候是快照讀,其余是當(dāng)前讀映皆,所以挤聘,mvvc不能根本上解決幻讀的情況