數據庫中的丟失更新,臟讀,不可重復讀,幻讀


1.丟失更新

A事務撤銷時,把已經提交的B事務的更新數據覆蓋了。

 

 

 

 

2.臟讀

臟讀發生在一個事務A讀取了被另一個事務B修改,但是還未提交的數據。
假如B回退,則事務A讀取的是無效的數據。

 

 

 

 

3.不可重復讀

 

指在一個事務A內,多次讀同一個數據,但是事務A沒有結束時,另外一個事務B則修改了該數據。
那么事務A在 B事務修改數據之后再次讀取該數據, A事務讀到的數據可能和第一次讀到的數據不一樣。

 

這就發生了在一個事務內兩次讀到的數據不一樣,這就被稱作不可重復讀。

 

 

 

幻讀 (針對insert,delete操作)
幻讀發生在當兩個完全相同的查詢執行時,第二次查詢所返回的結果集跟第一個查詢不相同。

隔離級別
Read UnCommitted(讀未提交) - 解決丟失更新
最低的隔離級別。一個事務可以讀取另一個事務並未提交的更新結果。

Read Committed(讀提交) - 解決丟失更新,臟讀
大部分數據庫采用的默認隔離級別。一個事務的更新操作結果只有在該事務提交之后,另一個事務才可以的讀取到同一筆數據更新后的結果。

Repeatable Read(重復讀) - 解決丟失更新,臟讀,不可重復讀
mysql的默認級別。整個事務過程中,對同一筆數據的讀取結果是相同的,不管其他事務是否在對共享數據進行更新,也不管更新提交與否。

Serializable(序列化) - 解決丟失更新,臟讀,不可重復讀,幻讀
最高隔離級別。所有事務操作依次順序執行。注意這會導致並發度下降,性能最差。通常會用其他並發級別加上相應的並發鎖機制來取代它。

 

解決上述數據操作不一致的問題,數據庫通過鎖機制來解決。按鎖對象來分分為行級鎖和表級鎖;根據並發事務鎖定的關系上看:分為共享鎖和獨占鎖。為了更改數據,數據庫必須在進行更改的行上施加行獨占鎖定,一般的insert update delete都會隱式采用必要的行鎖定。基於鎖機制,數據庫面提供了4級事務隔離級別,用戶只需要設置事務的隔離級別,就會分析事務的sql語句並自動選擇合適的鎖。值得注意的是,隔離級別越高,數據庫的並發性能越差,即事務的隔離級別與數據庫的並發性能成負相關關系。

隔離級別具體具體內容如下圖所示:

 

不可重復讀和幻讀的區別已經如何解決

 

不可重復讀:A事務在執行過程中,B事務對數據進行了修改或刪除,導致A兩次讀取的數據不一致;
重點在於update和delete(鎖行即可解決),
幻讀:A事務在執行過程中,B事務新增了符合A事務要查詢的數據,導致A兩次讀取的數據不一致;
重點在於insert(需要鎖表解決)。

如果使用鎖機制來實現這兩種隔離級別,在可重復讀中,該sql第一次讀取到數據后,就將這些數據加鎖,其它事務無法修改這些數據,就可以實現可重復讀了。但這種方法卻無法鎖住insert的數據,所以當事務A先前讀取了數據,或者修改了全部數據,事務B還是可以insert數據提交,這時事務A就會發現莫名其妙多了一條之前沒有的數據,這就是幻讀,不能通過行鎖來避免。需要Serializable隔離級別 ,讀用讀鎖,寫用寫鎖,讀鎖和寫鎖互斥,這么做可以有效的避免幻讀、不可重復讀、臟讀等問題,但會極大的降低數據庫的並發能力。

所以說不可重復讀和幻讀最大的區別,就在於如何通過鎖機制來解決他們產生的問題。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM