基本的資料庫併發控制

2021-04-07 08:46:07 字數 2543 閱讀 3809

對於多使用者系統,資料庫操作的併發問題很常見,造成的錯誤如,資料丟失,讀取錯誤資料等。究其本質原因其實是資料不一致:乙個程序讀入記憶體中的資料和資料庫中的「同一批」資料在某一時刻已經不一樣了(可能資料庫中的資料被另外乙個程序修改了),但程式並不知道,於是造成各種錯誤。

主要要解決的是離線併發問題,其他併發問題通常可以通過系統事務和簡單邏輯解決。離線併發通常都與業務邏輯有關,當不可避免時,我們期望的是業務事務能象系統事務一樣工作。但長的業務事務有時不能放在乙個系統事務中(不靈活,降低了併發性),於是就要自己控制這種跨系統事務的業務事務的併發問題。當業務邏輯比較複雜時,要在正確性和併發性之間權衡一下,這兩方面有時是矛盾的,沒法得到完美的解決。比如,有的處理可能會使某種操作不正確,但它影響很小,不會帶來損失,但能提高系統的併發性,這樣的正確性可以犧牲。

既然本質原因是資料不一致,要解決問題一般要從兩方面入手:

1.禁止出現資料不一致的情況。

也就是要使用鎖,把資料庫中相關資料鎖起來,不允許其它程序修改,當業務事務完成後再釋放鎖。把資源變成獨佔式的,能避免資料不一致。系統事務也就是這個原理,其鎖是資料庫底層維護的。這種方式會造成不靈活,降低併發性,因為當乙個程序執行某個業務事務時,其他程序都不能做相關操作。

最簡單的方法是把整個業務事務都放在乙個系統事務內執行(這就不是離線併發問題了),帶來的問題是,當乙個程序執行業務事務時,其它程序做相關操作就會進入無響應的等待狀態,如果業務事務持續一天,其它程序可能就會等待一天,還可能會造成死鎖。

既然使用了鎖,就要防止死鎖。想一想,死鎖要具有兩個必要條件:一,當持有對某些資源的鎖時又去請求新的資源;二,如果請求的資源已經被別人鎖住,就進入等待狀態。這兩個條件缺乙個都不會出現死鎖。

比較好的方式就是自己控制鎖。可以在應用伺服器端的記憶體或資料庫中開闢乙個區域專門維護鎖。例如,在資料庫中建乙個鎖表或給每條資料加乙個鎖欄位,要鎖住某條資料時,就標誌一下,當其它程序要做相關操作時先檢查資料是否已經被鎖住,如果已經被鎖住,就不再繼續執行。當然,還可以根據業務邏輯,給一組資料設定乙個鎖。這與系統事務不同的是,當請求的資源被鎖住時,不是進入等待狀態,而是放棄繼續執行,提高了靈活性(使用者可以進行其它操作),還能有效降低死鎖的可能性(使之不滿足死鎖的第二個條件)。但這種控制方式是最麻煩的,開發者要弄清楚資料的業務邏輯,就是各個業務事務以及相互的關係,還要涉及鎖管理和系統事務。還會涉及維護會話的問題,因為使用者可能會非正常結束業務的執行(宕機,網路中斷,停電,地球不轉等),會留下沒有釋放的鎖。伺服器必須做到,如果某個使用者已經非正常停止了會話,就釋放會話過程中的鎖。

另外,要防止死鎖,在開發過程中應該注意,當執行某個操作時,盡量開始時就一次性的鎖住所有需要的資源,在執行過程中不再請求其它資源(使之不滿足死鎖的第乙個條件),操作結束後釋放鎖。如果要更謹慎一些,有時還可以給鎖加上時間限制,當乙個鎖超過一定時間後就自動失效,在鎖過程中所做的操作也都變得無效,這其實是使之不滿足死鎖的第二個條件。

2.允許資料不一致,但資料更新時要進行一致性檢查。

從資料庫中讀出一批初始資料,依據這些資料做了一系列的操作,當把操作結果更新到資料庫時,先檢查資料庫中那「同一批」初始資料是否已經發生了變化,如果發生了變化,根據業務需要,進行一定的處理。這種方式併發性強,比較靈活,而且是不加鎖的,這就避免了不少麻煩問題,實現起來要簡單一些。

簡單考慮,檢查資料一致性時,可以檢查資料庫中資料和記憶體中資料的值是否相同。但如果資料量較大,這種檢查恐怕效率很低。其實一致性檢查要考慮粒度問題,根據實際情況選擇合適的粒度。檢查具體資料的值是否變化,可以說是最細的粒度。可以通過資料的版本控制來實現更粗粒度的檢查。以資料記錄為單位進行版本管理,可以在資料表中加乙個整型字段作為版本。當

insert

一條資料時,設定乙個初始版本值。當

update

資料時,先檢查資料庫中的版本值是否發生了變化,如果沒有變化才執行

update

,並將被更新的資料版本值加

1。根據業務邏輯,有時要把一組資料使用乙個版本來管理(更粗的粒度),這可以使用乙個專門儲存版本的表來實現。要注意的是,一致性檢查和資料更新一定要在同乙個系統事務中進行,才能保證一致性。

沒有完美的世界,這種方式的缺點是,當提交更新時才會發現不一致,以至於提交之前的所有操作可能都變得無效。例如,使用者先從資料庫中讀出一些初始資料,然後做了大量的修改或錄入工作,弄了兩三個小時,最後提交時系統檢查到資料不一致問題,結果提交失敗,工作都白做了,於是使用者就會很鬱悶,於是就會開始不想使用這樣的系統,這是我們不希望看到的。乙個緩解的辦法是,除了在最後提交時檢查一致性外,可以在業務事務進行過程中,時不時的就檢查一下,越早發現不一致就可以越早的處理。這也只是緩解,不能從根本上解決。

第一類方法被稱為樂觀併發控制方法,第二類方法被稱為悲觀併發控制方法(「大家們」都喜歡弄出一些有趣的名詞來)。總之,離線併發問題不止是技術問題,首先要深入分析系統的業務邏輯,弄清楚系統在何時何地可能會出現什麼樣的併發問題,再根據具體情況和實際需要,權衡利弊,選擇合適的解決方法。應該先考慮長系統事務,如果能接受把整個業務事務都放在乙個系統事務中,就避免了離線併發問題。如果不能接受,再考慮樂觀控制方法,畢竟這個實現起來要相對簡單一些,但只當併發衝突發生的頻率較低,可能性較小時,才適合使用樂觀方法(如果使用者總是提交失敗,就更加對這樣的系統深惡痛絕了)。然後再考慮悲觀控制方法,雖然麻煩,但可用於併發衝突發生頻率較高的情況,實際上是限制了系統的併發性。

資料庫併發控制

資料庫併發控制 1 在資料庫中為什麼要併發控制?答 資料庫是共享資源,通常有許多個事務同時在執行。當多個事務併發地訪問資料庫時就會產生同時讀取和 或修改同一資料的情況。若對併發操作不加控制就可能會訪問和儲存不正確的資料,破壞資料庫的一致性。所以資料庫管理系統必須提供併發控制機制。2 併發操作可能會產...

資料庫併發控制

acid,是指在可靠資料庫管理系統 dbms 中,事務 transaction 所應該具有的四個特性 a 原子性 atomicity 事務是乙個或多個行為 在一起組成乙個單獨的工作單元,事務中的動作要不都發生,要不都不發生.c 一致性 consistent 即在事務開始之前和結束之後,資料庫的完整性...

資料庫併發控制

資料庫是乙個資源庫,可以供多個使用者使用.允許多個使用者同時使用同乙個資料庫的資料庫系統稱為多使用者資料庫系統.例如飛機訂票資料庫系統 銀行資料庫系統.在多使用者資料庫系統中同乙個時刻會有很多個併發執行的事務.1.提高吞吐量和資源利用率 乙個事務由多個步驟組成,一些步驟涉及i o活動,另一些涉及cp...