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