數據庫4種隔離級別與3級封鎖協議


數據庫並發會引發的問題

  • 臟讀(dirty read):A事務讀取B事務尚未提交的更改數據,並在這個數據基礎上操作。如果B事務回滾,那么A事務讀到的數據根本不是合法的,稱為臟讀。在oracle中,由於有version控制,不會出現臟讀
  • 不可重復讀(unrepeatable read):A事務讀取了B事務已經提交的更改(或刪除)數據。比如A事務第一次讀取數據,然后B事務更改該數據並提交,A事務再次讀取數據,兩次讀取的數據不一樣
  • 幻讀(phantom read):A事務讀取了B事務已經提交的新增數據。注意和不可重復讀的區別,這里是新增,不可重復讀是更改(或刪除)。這兩種情況對策是不一樣的,對於不可重復讀,只需要采取行級鎖防止該記錄數據被更改或刪除,然而對於幻讀必須加表級鎖,防止在這個表中新增一條數據
  • 第一類丟失更新:A事務撤銷時,把已提交的B事務的數據覆蓋掉
  • 第二類丟失更新:A事務提交時,把已提交的B事務的數據覆蓋掉

讀未提交

最低隔離級別,允許一個事務能夠讀到另一個事務未提交的信息,只對修改數據的並發操作做限制(對於數據而言,寫之前加X鎖,直到事務結束釋放X鎖,對應一級封鎖協議),這樣解決了第一類丟失更新的問題,雖然一個事務不能修改其他事務正在修改的數據,但是可以讀到其他事務還未提交的修改,如果這些修改未提交,那么就會成為臟數據,所以還未解決臟讀的問題,自然,就算是已經提交的數據,多次讀取結果也不一定一樣,所以還未解決不可重復讀幻讀的問題(存在的問題:臟讀,不可重復讀,幻讀

讀已提交

只能讀取已經提交的數據,換句話說,就是一個事務讀取其他事務中正在修改的數據是不被允許的(一級封鎖協議+讀之前加S鎖,讀完數據釋放S鎖,對應二級封鎖協議),由於讀完之后就釋放S鎖,所以不能保證不可重復讀幻讀

可重復讀

讀已提交下,同一事務內,允許多次相同的查詢能夠得到不同的結果,可以使用二級封鎖協議+MVCC使得當前事務只能讀取不高於其事務版本的數據,也可以使用三級封鎖協議(一級封鎖協議+讀之前加S鎖,直到事務結束釋放S鎖)能解決可重復讀

可串行化

可重復讀與幻讀的區別是:可重復讀是更改表中行級數據,而幻讀是增加表中行級數據,可串行化使得所有的事務必須串行化執行,解決了一切並發問題,但會造成大量的等待、阻塞甚至死鎖,使系統性能降低

參考

MySQL隔離級別和封鎖協議


免責聲明!

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



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