數據庫中的事務是併發操作的,併發操作可以提高系統的工作效率,節省資源。在事務併發操作時,會出現多個事務對某一資源的爭用,多個事務對資源進行不同的操作,若不加以控制,會出現數據不一致的問題。因此,在DBMS中需要進行併發控制管理。
併發控制的問題
若不對併發事務進行控制,會出現數據不一致的問題,如髒讀、不可重複讀、幻讀、丟失更新等問題。
-
髒讀
多個事務併發運行,訪問共享數據,其中一個事務讀取了被另一個事務修改的共享數據,但修改數據的那個事務發生了錯誤,並沒有提交事務,此時讀取的數據就是髒數據(未提交的修改數據)。 -
不可重複讀
多個事務併發執行時,一些事務對共享數據進行多次讀操作,但其中一些事務對共享數據進行了修改或刪除操作,導致原有數據改變或丟失。 -
幻讀
多個事務併發執行時,其中一個事務對共享數據進行了添加操作,導致讀兩次時,第二次數據比第一次數據新增了一些數據。 -
丟失更新
多個事務併發執行時,其中一個事務對共享數據進行了更新,並改變了前面事務的更新值,導致一個事務對共享數據進行更新,但查詢的數據和更新的值不一致。
鎖機制
在DBMS中,鎖表機制與併發控制調度器結合,實現共享資源的鎖定訪問。
根據鎖定資源類型鎖可分爲:
- 排他鎖(Exclusive Lock):限制其他事務對共享數據的修改、刪除和查詢操作;
- 共享鎖(Share Lock):限制其他事務對共享數據的修改、刪除。
另外鎖機制還可以運用在多種粒度上,如數據庫、表、頁面、行。鎖定的範圍越大,DMBS管理越容易。
鎖的相容性
當多個事務對共享資源進行加鎖時,操作是否成功,取決於鎖之間的相容性。
類型 | 排他鎖 | 共享鎖 | 無鎖 |
---|---|---|---|
排他鎖 | 否 | 否 | 是 |
共享鎖 | 否 | 是 | 是 |
無鎖 | 是 | 是 | 是 |
加鎖協議
加鎖協議規定了何時使用排他鎖和共享鎖,何時釋放鎖。不同規則的加鎖協議,解決的數據庫一致性問題是不同的。
加鎖協議級別 | 排他鎖 | 共享鎖 | 不丟失更新 | 不髒讀 | 可重複讀 |
---|---|---|---|---|---|
一級 | 全程加鎖 | 不加 | 是 | 否 | 否 |
二級 | 全程加鎖 | 開始時加鎖,讀完數據釋放鎖定 | 是 | 是 | 否 |
三級 | 全程加鎖 | 全程加鎖 | 是 | 是 | 是 |
兩階段鎖定協議指的是所有併發事務在進行共享數據操作處理時,必須按照兩個階段(增長、縮減)對共享數據進行加鎖和解鎖申請。在增長階段,事務可以對共享數據進行加鎖申請,但不能釋放已有的鎖定;在縮減階段,事務可以對已有的鎖定進行釋放,但不能對共享數據提出新的加鎖申請。
在併發事務運行中,若所有事務都遵從兩階段鎖定協議,即可保持數據一致性。
死鎖問題
在事務併發運行中,若事務同時鎖定兩個及以上資源時,可能會出現彼此都不能繼續運行的狀態,即死鎖狀態。
- 出現死鎖的必要條件
(1)互斥條件:事務對所分配的資源加排他鎖,在一段時間內某資源只由一個事務佔用;
(2)請求和保持條件:事務已經保持了至少一個資源,但又提出新的資源請求,但該資源被其他資源佔用,此時請求事務被阻塞,又不釋放已佔用資源;
(3)不剝奪條件:事務佔用已獲得資源,在未使用完前,不能被剝奪,只能在使用完時自動釋放;
(4)環路等待條件:事務T0在等待事務T1佔用的資源,事務T1在等待事務T2佔用的資源,依此類推,事務Tn在等待事務T0佔用的資源,造成環路等待。 - 解決方式
(1)在併發事務執行之前,預防死鎖;
(2)在死鎖出現後,其中一個事務釋放資源解除死鎖。
這些是數據庫系統採用的兩種策略用於解決死鎖。
事務隔離級別
爲了避免在事務併發時,出現讀髒數據、不可重讀、幻讀等問題,可以在DBMS中設置隔離級別來避免出現事務併發帶來的問題。
隔離級別 | 髒讀 | 不可重複讀 | 幻讀 | 丟失更新 |
---|---|---|---|---|
讀取未提交(Read Uncommitted) | 可能 | 可能 | 可能 | 可能 |
讀取已提交(Read Committed) | 不可能 | 可能 | 可能 | 可能 |
可重複讀 (Repeatable Read) | 不可能 | 不可能 | 可能 | 可能 |
可串行化(Serializable) | 不可能 | 不可能 | 不可能 | 不可能 |