概述:
我們可以使用兩種形式的並發控制策略:開放式並行存取控制和封閉式並行存取控制。
假設martin和David同時都要編輯Customer檔案。如果使用樂觀鎖策略,他們兩個人都能得到一份檔案的Copy,並且
可以自由編輯檔案。假設David第一個完成了工作,那麼他可以毫無困難地更新他的修改。但是,當Martin想要提交他的修改時,並發控制策略就會開始起作用。原始碼控制系統會檢測到在Martin的修改與David的修改之間存在著衝突,因而拒絕Martin的提交,並由Martin負責指出怎樣處理這種情況。如果使用悲觀鎖策略,只要有人先取出檔案,其他人就不能對該檔案進行編輯。因此,假如是Martin先取了檔案,那麼David就只能在Martin完成任務並提交之後才能對該檔案進行操作。
如果把樂觀鎖看作是關於衝突檢測的,那麼悲觀鎖就是關於衝突避免的。在實際應用的原始碼控制系統中,
這兩種策略都可以被使用,但是現在大多數原始碼開發人員更傾向於使用樂觀鎖策略。(有一種很有道理的說法:樂觀鎖並不是真正的鎖定,但是這種叫法很方便並且廣泛流傳,以至於不容忽略。)
這兩種策略各有優缺點。悲觀鎖的問題是減少了並發的程式。當Martin正對一個被他加鎖的檔案進行編輯的時候,
其它人只能等著。使用過悲觀的原始碼控制人都知道這是一種多麼令人喪氣的事情。對於企業資料,情況經常會變得更加糟糕,只要有人在編輯,其他人就無法進行讀取,更加說進行編輯了。
樂觀鎖策略則允許人們更自由一些,因為只有在提交的時候才有可能遇到阻礙。該策略的問題在於當衝突的時候會發生什麼樣的事情呢。事實上,David之後的所有人在提交的時候都必須讀取David修改過的那個版本,並指出怎樣合并自己和David的修改,然後再提交一個重新修改過的最新版本。有了原始碼控制系統,這樣做並不會有什麼麻煩。在許多場合下,原始碼控制系統確實能夠自動進行合併作業,甚至在無法自動合并的時候,也能讓使用都很容易看出不同檔案版本之間的差別。但是,業務資料通常都是很難被自動合并的,所以經常只能扔掉原來的東西,然後從頭開始。
在樂觀鎖和悲觀鎖之間進行選擇的標準是:衝突的頻率與嚴重性。如果衝突很少,或者衝突的後果不會很嚴重,那麼通常情況下應該選擇樂觀鎖,因為它能得到更好的並發性,而且更容易實現。但是,如果衝突的結果對於使用者來說痛苦的,那麼就需要使用悲觀策略。
樂觀鎖的局限是:只能在提交資料時才發現業務事務將要失敗,而且在某些情況下,發現失敗太遲的代價會很大。使用者可能花了一個小時的時間輸入一份租約的詳細資料,錯誤太多會讓使用者對系統失去信心。另一個方法是使用悲觀鎖,它可以儘早地發現錯誤,但理難以編程實現,而且會降低系統的靈活性。
(註:以上是對並發控制中的樂觀鎖策略和悲觀鎖策略概念及解決思路的文字描述,下面我將對項目中具體怎麼實現樂觀鎖策略及悲觀鎖策略進行描述。)
樂觀鎖策略實現方法:
就是用C#中或SQL中的事務來實現資料操作不成功就復原,個人感覺火車站賣票系統也是這樣操作的,我們看到顯示屏上有少量剩餘票,但我們去買又打不出來。
悲觀鎖策略實現方法:
1、普通的aspx頁面,當使用者點提交後,直接將提交及相關按鈕的enabel改為false,直到提交事件完成後,再改回來。另外在資料層那一塊,每次提交資料更改時,都需要判斷資料以前的狀態是否改變,以防止有並發改變的情況出現。
2、jquery中,在jquery中,可以設定一個全域變數,提交時,先判斷全域變數狀態,如不允許提交則直接返回,如允許提交時,則先將全域變數置為“不允許提交”,後開始提交,提交完成後,在jquery的post方法的callback方法中,再將全域變數改為“允許提交”。
3、彈出式視窗修改頁面,則用模態方式彈出,如web頁面中,可用window.showModalDialog()來實現模態方式開啟修改頁面,來確保始終只有一個修改頁面被開啟。(這是從資料操作頁面處就悲觀鎖定了資料,而不是在資料庫裡面悲觀鎖定)