1. 程式人生 > >樂觀併發控制與悲觀併發控制的區別

樂觀併發控制與悲觀併發控制的區別

悲觀併發控制
一個鎖定系統,可以阻止使用者以影響其他使用者的方式修改資料。如果使用者執行的操作導致應用了某個鎖,只有這個鎖的所有者釋放該鎖,其他使用者才能執行與該鎖衝突的操作。這種方法之所以稱為悲觀併發控制,是因為它主要用於資料爭用激烈的環境中,以及發生併發衝突時用鎖保護資料的成本低於回滾事務的成本的環境中。 
樂觀併發控制 
在樂觀併發控制中,使用者讀取資料時不鎖定資料。當一個使用者更新資料時,系統將進行檢查,檢視該使用者讀取資料後其他使用者是否又更改了該資料。如果其他使用者更新了資料,將產生一個錯誤。一般情況下,收到錯誤資訊的使用者將回滾事務並重新開始。這種方法之所以稱為樂觀併發控制,是由於它主要在以下環境中使用:資料爭用不大且偶爾回滾事務的成本低於讀取資料時鎖定資料的成本。
具體的區別與例項說明如下:

悲觀併發控制:假設A和B需要在SCC(Source Code Control)上修改同一個檔案,那麼在A鎖定這個檔案並修改的過程中,B無法修改這個檔案,他只能等待A解鎖檔案後,他才能修改。由此可見,悲觀併發控制是強調控制在前,確保整個過程不會出現檔案版本的衝突。這樣做會使得系統效率損耗在加鎖機制上,尤其是加鎖機制需要用到低速的外部儲存(比如FileLocking)時,然而這樣做就降低了事務的併發性,尤其是事務之間本來就不存在衝突的情況下。例如在A修改資料的時候,B只能等待。

由此可見,悲觀併發控制通過使用顯式的加鎖機制或者時間戳,對每一個事務進行增量同步校驗。如果加鎖機制的成本較高的話,悲觀併發控制就會出現一些弊端。首先就是效率問題,尤其是使用低效率的外部儲存系統實現加鎖機制時,這樣的問題會更加突出。其次,在不會出現衝突的事務處理(例如只讀型事務)中,使用加鎖機制就顯得沒有必要了,這樣做只能增加系統負載。再次,這種方式降低了系統的併發性。

樂觀併發控制:同樣假設A和B需要在SCC上修改同一個檔案,他們都將這個檔案獲取到自己的機器上,A修改完以後,就把檔案上傳到SCC上了,此時B也修改完了,當他也打算將檔案上傳時,系統會告知B,已經有人上傳了,並出現一個錯誤。剩下的問題只能由B手動解決,例如B可以在SCC上將檔案中更改的內容再次複製一遍。樂觀併發控制使得系統效率損耗在事務的後期處理中,比如B必須手動的去修改他已經修改過的東西,然而這種控制方式在極少出現衝突的多事務處理中顯得十分高效。

樂觀併發控制將事務分為三個階段:讀取階段、校驗階段以及寫入階段。在讀取階段,事務將資料寫入本地緩衝(如上所述,A和B將檔案都獲取到自己的機器上),此時不會有任何校驗操作;在校驗階段,系統會對所有的事務進行同步校驗(比如在A或者B打算,但還沒有,往SCC上寫入更改後的檔案時);在寫入階段,資料將被最終提交。在完成讀取階段以後,系統會對每個事務分派一個時間戳。

悲觀併發控制中一個常見的問題就是死鎖。例如A在修改檔案T1,B在修改檔案T2,他們分別鎖定了這兩個檔案,假設T1和T2內容相關,B在修改T2的時候發現他還需要修改T1,可是T1卻被A鎖定;與此同時,A在修改T1的時候也發現了他還需要修改T2,可是T2又被B鎖定了,這樣就出現了死鎖。當然,在實際操作中,這種情況可以由A和B協商解決,但是在錯綜複雜的多事務處理環境中,死鎖將使得問題變得非常複雜。

參考連結:https://www.cnblogs.com/Fandyx/archive/2012/07/14/2591153.html