當然, 從總的結果來看, 似乎兩者都表現為兩次讀取的結果不一致.
但如果你從控制的角度來看, 兩者的區別就比較大
對於前者, 只需要鎖住滿足條件的記錄
對於後者, 要鎖住滿足條件及其相近的記錄
我這麼理解是否可以?
避免不可重複讀需要鎖行就行
避免幻影讀則需要鎖表
####不可重複讀和幻讀的區別####
很多人容易搞混不可重複讀和幻讀,確實這兩者有些相似。但不可重複讀重點在於update和delete,而幻讀的重點在於insert。
如果使用鎖機制來實現這兩種隔離級別,在可重複讀中,該sql第一次讀取到資料後,就將這些資料加鎖,其它事務無法修改這些資料,就可以實現可重複
讀了。但這種方法卻無法鎖住insert的資料,所以當事務a先前讀取了資料,或者修改了全部資料,事務b還是可以insert資料提交,這時事務a就會
發現莫名其妙多了一條之前沒有的資料,這就是幻讀,不能通過行鎖來避免。需要serializable隔離級別
,讀用讀鎖,寫用寫鎖,讀鎖和寫鎖互斥,這麼做可以有效的避免幻讀、不可重複讀、髒讀等問題,但會極大的降低資料庫的併發能力。
所以說不可重複讀和幻讀最大的區別,就在於如何通過鎖機制來解決他們產生的問題。
上文說的,是使用悲觀鎖機制來處理這兩種問題,但是mysql、oracle、postgresql等成熟的資料庫,出於效能考慮,都是使用了以樂觀鎖為理論基礎的mvcc(多版本併發控制)來避免這兩種問題。
####悲觀鎖和樂觀鎖####
正如其名,它指的是對資料被外界(包括本系統當前的其他事務,以及來自外部系統的事務處理)修改持保守態度,因此,在整個資料處理過程中,將資料處
於鎖定狀態。悲觀鎖的實現,往往依靠資料庫提供的鎖機制(也只有資料庫層提供的鎖機制才能真正保證資料訪問的排他性,否則,即使在本系統中實現了加鎖機
制,也無法保證外部系統不會修改資料)。
在悲觀鎖的情況下,為了保證事務的隔離性,就需要一致性鎖定讀。讀取資料時給加鎖,其它事務無法修改這些資料。修改刪除資料時也要加鎖,其它事務無法讀取這些資料。
相對悲觀鎖而言,樂觀鎖機制採取了更加寬鬆的加鎖機制。悲觀鎖大多數情況下依靠資料庫的鎖機制實現,以保證操作最大程度的獨占性。但隨之而來的就是資料庫效能的大量開銷,特別是對長事務而言,這樣的開銷往往無法承受。
而樂觀鎖機制在一定程度上解決了這個問題。樂觀鎖,大多是基於資料版本( version
)記錄機制實現。何謂資料版本?即為資料增加乙個版本標識,在基於資料庫表的版本解決方案中,一般是通過為資料庫表增加乙個 「version」
欄位來實現。讀取出資料時,將此版本號一同讀出,之後更新時,對此版本號加一。此時,將提交資料的版本資料與資料庫表對應記錄的當前版本資訊進行比對,如
果提交的資料版本號大於資料庫表當前版本號,則予以更新,否則認為是過期資料。
要說明的是,mvcc的實現沒有固定的規範,每個資料庫都會有不同的實現方式,這裡討論的是innodb的mvcc。
不可重複讀和幻讀的區別
1,不可重複讀是指事務a讀取表中資料的時候,此時事務b對該資料進行了修改,導致事務a再次讀取該資料時,發現不一樣 兩次讀取相同的資料產生不同的結果 2,幻讀是指事務a在修改某錶中的全部資料時,已經修改完畢,此時事務b又新插入一條記錄,導致事務a再次讀取該表中資料時,發現還有未修改的記錄,產生了幻覺 ...
髒讀,不可重複讀,幻讀區別
在了解髒讀,不可重複度,幻讀之前,首先要明白這三種情況的出現都是和資料庫併發事務有關聯的,如果所有的讀寫都按照佇列的形式進行,就不會出現問題。名詞解析和解決方案 髒讀 髒讀又稱無效資料讀出 讀出了髒資料 乙個事務讀取另外乙個事務還沒有提交的資料叫髒讀。例如 事務t1修改了某個表中的一行資料,但是還沒...
髒讀,不可重複讀,幻讀的區別
1.髒讀 髒讀是指在乙個事務處理過程裡讀取了另乙個未提交的事務中的資料。當乙個事務正在多次修改某個資料,而在這個事務中這多次的修改都還未提交,這時乙個併發的事務來訪問該資料,就會造成兩個事務得到的資料不一致。2.不可重複讀 不可重複讀是指在對於資料庫中的某個資料,乙個事務範圍內多次查詢卻返回了不同的...