當然, 從總的結(jié)果來看, 似乎兩者都表現(xiàn)為兩次讀取的結(jié)果不一致.
但如果你從控制的角度來看, 兩者的區(qū)別就比較大
對于前者, 只需要鎖住滿足條件的記錄
對于后者, 要鎖住滿足條件及其相近的記錄
我這么理解是否可以?
避免不可重復讀需要鎖行就行
避免幻影讀則需要鎖表
不可重復讀和幻讀的區(qū)別####
很多人容易搞混不可重復讀和幻讀此改,確實這兩者有些相似。但不可重復讀重點在于update和delete,而幻讀的重點在于insert靶庙。
如果使用鎖機制來實現(xiàn)這兩種隔離級別陷嘴,在可重復讀中,該sql第一次讀取到數(shù)據(jù)后旦棉,就將這些數(shù)據(jù)加鎖疲眷,其它事務(wù)無法修改這些數(shù)據(jù)禾蚕,就可以實現(xiàn)可重復 讀了。但這種方法卻無法鎖住insert的數(shù)據(jù)狂丝,所以當事務(wù)A先前讀取了數(shù)據(jù)换淆,或者修改了全部數(shù)據(jù),事務(wù)B還是可以insert數(shù)據(jù)提交美侦,這時事務(wù)A就會 發(fā)現(xiàn)莫名其妙多了一條之前沒有的數(shù)據(jù)产舞,這就是幻讀,不能通過行鎖來避免菠剩。需要Serializable隔離級別 易猫,讀用讀鎖,寫用寫鎖具壮,讀鎖和寫鎖互斥准颓,這么做可以有效的避免幻讀、不可重復讀棺妓、臟讀等問題攘已,但會極大的降低數(shù)據(jù)庫的并發(fā)能力。
所以說不可重復讀和幻讀最大的區(qū)別怜跑,就在于如何通過鎖機制來解決他們產(chǎn)生的問題样勃。
上文說的,是使用悲觀鎖機制來處理這兩種問題性芬,但是MySQL峡眶、ORACLE、PostgreSQL等成熟的數(shù)據(jù)庫植锉,出于性能考慮辫樱,都是使用了以樂觀鎖為理論基礎(chǔ)的MVCC(多版本并發(fā)控制)來避免這兩種問題。
悲觀鎖和樂觀鎖####
悲觀鎖
正如其名俊庇,它指的是對數(shù)據(jù)被外界(包括本系統(tǒng)當前的其他事務(wù)狮暑,以及來自外部系統(tǒng)的事務(wù)處理)修改持保守態(tài)度,因此辉饱,在整個數(shù)據(jù)處理過程中搬男,將數(shù)據(jù)處 于鎖定狀態(tài)。悲觀鎖的實現(xiàn)彭沼,往往依靠數(shù)據(jù)庫提供的鎖機制(也只有數(shù)據(jù)庫層提供的鎖機制才能真正保證數(shù)據(jù)訪問的排他性止后,否則,即使在本系統(tǒng)中實現(xiàn)了加鎖機 制溜腐,也無法保證外部系統(tǒng)不會修改數(shù)據(jù))译株。
在悲觀鎖的情況下,為了保證事務(wù)的隔離性挺益,就需要一致性鎖定讀歉糜。讀取數(shù)據(jù)時給加鎖,其它事務(wù)無法修改這些數(shù)據(jù)望众。修改刪除數(shù)據(jù)時也要加鎖匪补,其它事務(wù)無法讀取這些數(shù)據(jù)。
樂觀鎖
相對悲觀鎖而言烂翰,樂觀鎖機制采取了更加寬松的加鎖機制夯缺。悲觀鎖大多數(shù)情況下依靠數(shù)據(jù)庫的鎖機制實現(xiàn),以保證操作最大程度的獨占性甘耿。但隨之而來的就是數(shù)據(jù)庫性能的大量開銷踊兜,特別是對長事務(wù)而言,這樣的開銷往往無法承受佳恬。
而樂觀鎖機制在一定程度上解決了這個問題捏境。樂觀鎖,大多是基于數(shù)據(jù)版本( Version )記錄機制實現(xiàn)毁葱。何謂數(shù)據(jù)版本垫言?即為數(shù)據(jù)增加一個版本標識,在基于數(shù)據(jù)庫表的版本解決方案中倾剿,一般是通過為數(shù)據(jù)庫表增加一個 “version” 字段來實現(xiàn)筷频。讀取出數(shù)據(jù)時,將此版本號一同讀出前痘,之后更新時凛捏,對此版本號加一。此時际度,將提交數(shù)據(jù)的版本數(shù)據(jù)與數(shù)據(jù)庫表對應記錄的當前版本信息進行比對葵袭,如 果提交的數(shù)據(jù)版本號大于數(shù)據(jù)庫表當前版本號,則予以更新乖菱,否則認為是過期數(shù)據(jù)坡锡。
要說明的是,MVCC的實現(xiàn)沒有固定的規(guī)范窒所,每個數(shù)據(jù)庫都會有不同的實現(xiàn)方式鹉勒,這里討論的是InnoDB的MVCC。
轉(zhuǎn)自:https://www.cnblogs.com/itcomputer/articles/5133254.html