悲觀鎖定與樂觀鎖定 第6章 鎖

2022-02-17 15:30:11 字數 2262 閱讀 9584

expert oracle database architecture學習筆記

悲觀鎖定與樂觀鎖定(第6章.鎖)

為了避免丟失更新,要使用某種鎖定策略,共有兩種鎖定策略:悲觀鎖定或樂觀鎖定。

悲觀鎖定(pessimistic locking):

使用者在螢幕上修改值之前,這個鎖定方法就要起作用。例如,使用者一旦有意對他選擇的某個特定行(螢幕上可見)執行更新,如單擊螢幕上的乙個按鈕,就會放上乙個鎖。

悲觀鎖定僅用於有狀態(stateful)或有連線(connected)的環境,這是20世紀90年代中期客戶/伺服器應用中的一種流行做法。但現在採用有狀態方式的連線方法已經不太常見了(不過並沒有完全消失),特別是隨著20世紀90年代中後期應用伺服器的出現,有狀態連線更是少見。

悲觀鎖定的例子:

select empno, ename, sal

from emp

where empno = :empno

and ename = :aname

and sal = :sal

for update nowait

樂觀鎖定(optimistic locking)

即把所有鎖定都延遲到即將執行更新之前才作。換句話說,我們會修改螢幕上的資訊而不要鎖。我們很樂觀,認為資料不會被其他使用者修改;因此,會等到最後一刻才會去看我們的想法對不對。

這種鎖定方法在所有環境下都行得通,但是執行更新的使用者「失敗」的可能性會增大。這個使用者要更新它的資料行時,發現資料已經修改過,所以他必須重頭再來。

可以在應用中同時保留舊值和新值,然後在更新資料庫時使用如下的更新語句,這是樂觀鎖定的一種流行實現:

updtae table

set column1 = :new_column1, column2 = :new_column2,...

where primary_key = :primary_key

and column1 = :old_column1

and column2 = :old_column2

...這種情況下,我們可能很幸運地更新了一行,但如果另乙個人已經修改了資料,我們就會失敗。現在我們必須確定下一步要做什麼,是讓終端使用者重新查詢這一行現在的新值,然後再重新開始新事物呢(但是這一行有可能又被修改了,這可能會使使用者很受打擊)?還是根據業務規則更新衝突,試圖合併兩個更新的值(這需要大量的**)?

另外,上面的update有可能被阻塞。如果所有應用(會話)都使用樂觀鎖定,執行更新並提交時,行只會被鎖定很短的時間。但如果某些應用使用了悲觀鎖定,它會在較長時間內持有行上的鎖,你可能就會考慮使用select for update nowait,以此來驗證行是否被修改,並在即將update之前鎖定來避免被另乙個會話阻塞。

另外三種實現樂觀併發控制的方法:

1、使用版本列的樂觀鎖定。

對每個要保護的表增加一列,這一列通常是number或date/timestamp列,通常通過行觸發器來維護。

在應用中只需儲存這個版本列的值,而不用儲存所有其他列的值。

為了維護這個版本列,建議把更新邏輯封裝到乙個儲存過程中。另乙個實現方法是使用觸發器,但是觸發器會引入大量開銷。

2、使用校驗和的樂觀鎖定

這與前面的版本列方法很相似,在此要使用計資料本身來計算乙個「虛擬的」版本列。有很多方法計算雜湊或校驗和。以下是其中的三種:

·owa_opt_lock.checksum:(oracle8.1.5)及以上版本中提供,出現衝突的可能性是1/65536。

·dbms_dbfuscation_toolkit.md5:(oracle8.1.7)及以上版本中提供,出現衝突的可能性是1/(3.4e+38),非常小。

·dbms_crypto.hsah:(oracle10.1)及以上版本中提供.

很多編成語言中都提供了一些雜湊和校驗和函式,所以還可以使用資料庫之外的雜湊和校驗和函式。

計算雜湊和校驗和是cpu密集型的操作,其計算代價很昂貴,但是其「網路友好性比較好」。

下面的ora_rowscn方法不僅很小(類似於雜湊),而且計算時不是cpu密集的。

3、使用ora_rowscn的樂觀鎖定

從oracle 10.1開始,你還可以使用內建的ora_rowscn函式,其原理與版本列技術很相似,但是可以由oracle自動執行,而不需要在表中增加額外的列,也不需要額外的**來更新維護這個值。

不管是悲觀鎖定還是樂觀鎖定都可以利用select for update nowaut查詢來驗證行未被修改。悲觀鎖定會在使用者有意修改資料那一刻使用這條語句。樂觀鎖定則在即將在資料庫中更新資料時使用這條語句。這樣不僅能解決應用中的阻塞問題,還可以修正資料完整性問題。

Oracle鎖定 悲觀與樂觀鎖詳解

oracle資料庫悲觀鎖與樂觀鎖是本文我們主要要介紹的內容。有時候為了得到最大的效能,一般資料庫都有併發機制,不過帶來的問題就是資料訪問的衝突。為了解決這個問題,大多數資料庫用的方法就是資料的鎖定 以下是 片段 select fromtestwhereid 10也就是沒有for update這種鎖定...

SQL SERVER樂觀鎖定和悲觀鎖定

在實際的多使用者併發訪問的生產環境裡邊,我們經常要盡可能的保持資料的一致性。而其中 最典型的例子就是我們從表裡邊讀取資料,檢查驗證後對資料進行修改,然後寫回到資料庫 中。在讀取和寫入的過程中,如果在多使用者併發的環境裡邊,其他使用者已經把你要修改的資料 進行了修改是非常有可能發生的情況,這樣就造成了...

SQL Server樂觀鎖定和悲觀鎖定例項

本文使用乙個例項來說明如何使用樂觀鎖定和悲觀鎖定來解決多使用者併發的環境裡,其他使用者已經把你要修改的資料進行了修改而造成資料的不一致的問題。在實際的多使用者併發訪問的生產環境裡邊,我們經常要盡可能的保持資料的一致性。而其中最典型的例子就是我們從表裡邊讀取資料,檢查驗證後對資料進行修改,然後寫回到資...