現在主流的數據庫管理系統中,都支持多個事務同時執行,這樣提高了數據庫管理系統的運行效率。試想如果只允許一個事務運行,而這個事務又需要很長的時間,那麼其他的用戶必須一直等待該事務結束,效率何其低下。執行不同的事務雖然可以提高性能,但是有可能會破壞數據的完整性,所以我們必須在性能和數據完整性之間進行權衡。那麼什麼是並發控制呢?並發控制是數據庫管理系統協調多個運行事務的行為。首先了解一下,並發控制中經常遇到的三個問題。
髒讀
我們通過一個products表來解釋一下什麼是髒讀,該products表有一列quantity(數量),現在的值為20。假如現在有兩個事務T1和T2,它們都是要更新quantity列,T1將該列值加100,T2將此列減10,但是T1執行失敗進行了回滾。我們很容易計算出正確的結果20-10=10,但是如果事務按照以下方式運行,能夠得出什麼結果?
時間 事務 步驟 存儲值
1 T1 讀出quantity的值 20
2 T1 quantity=20+100 120
3 T1 寫入quantity值 120
4 T2 讀出quantity(T1未提交) 120
5 T2 quantity=120-10 110
6 T1 回滾(rollback) 20
7 T2 寫入quantity值 110
以上得出了110的結果,顯然是不正確的,問題就在於T2讀取到了T1沒有提交的數據,我們把這種情況就稱之為髒讀。
不可重復讀
還是事務T1和T2,它們都是要更新quantity列,T1將該列值加100,T2將此列減10,而且兩個事務都成功。我們很容易計算出正確的結果20+100-10=110,但是如果事務按照以下方式運行,能夠得出什麼結果?
時間 事務 步驟 存儲值
1 T1 讀出quantity的值 20
2 T2 讀出quantity的值 20
3 T1 quantity=20+100 120
4 T2 quantity=20-10 10
5 T1 寫入quantity值(更新丟失) 110
6 T2 寫入quantity值 10
得出了10的結果,仍然是不正確的。問題就在於T2的值覆蓋了T1的值,我們把這種情況稱之為不可重復讀。
幻覺讀
例如T1對一個表中的所有行修改,同時T2向該表中插入一行記錄。這時在T1中就會發生還有沒有被修改的數據行,就好象發生了幻覺一樣。
SQL92標准定義了四種隔離級別,以解決以上問題,四種隔離級別如下圖所示: