Oracle鎖定 悲觀與樂觀鎖詳解

2021-06-03 17:19:52 字數 2102 閱讀 6871

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

以下是**片段:

select*fromtestwhereid=10也就是沒有for update這種鎖定資料的語句的話,就不會造成阻塞了。另外一種情況,就是當資料庫資料被鎖定的時候,也就是執行剛才for update那條sql以後,我們在另外乙個session中執行for update nowait後又是什麼樣呢。比如如下的sql語句。 由於這條語句中是制定採用nowait方式來進行檢索,所以當發現資料被別的session鎖定中的時候,就會迅速返回ora-00054錯誤,內容是資源正忙, 但指定以 nowait 方式獲取資源。所以在程式中我們可以採用nowait方式迅速判斷當前資料是否被鎖定中,如果鎖定中的話,就要採取相應的業務措施進行處理。

以下是**片段:

select*fromtestwhereid=10forupdatenowait那這裡另外乙個問題,就是當我們鎖定住資料的時候,我們對資料進行更新和刪除的話會是什麼樣呢。比如同樣,我們讓第乙個session鎖定住id=10的那條資料,我們在第二個session中執行如下語句。

以下是**片段:

updatetestsetvalue=2whereid=10這個時候我們發現update語句就好像select for update語句一樣也停住卡在這裡,當你第乙個session放開鎖定以後update才能正常執行。當你update執行後,資料又被你update語句鎖定住了,這個時候只要你update後還沒有commit,別的session照樣不能對資料進行鎖定更新等等。

總之,oracle中的悲觀鎖就是利用oracle的connection對資料進行鎖定。在oracle中,用這種行級鎖帶來的效能損失是很小的,只是要注意程式邏輯,不要給你一不小心搞成死鎖了就好。而且由於資料的及時鎖定,在資料提交時候就不呼出現衝突,可以省去很多惱人的資料衝突處理。缺點就是你必須要始終有一條資料庫連線,就是說在整個鎖定到最後放開鎖的過程中,你的資料庫聯接要始終保持住。與悲觀鎖相對的,我們有了樂觀鎖。樂觀鎖一開始也說了,就是一開始假設不會造成資料衝突,在最後提交的時候再進行資料衝突檢測。

在樂觀鎖中,我們有3種常用的做法來實現:

[1]第一種就是在資料取得的時候把整個資料都copy到應用中,在進行提交的時候比對當前資料庫中的資料和開始的時候更新前取得的資料。當發現兩個資料一模一樣以後,就表示沒有衝突可以提交,否則則是併發衝突,需要去用業務邏輯進行解決。

[2]第二種樂觀鎖的做法就是採用版本戳,這個在hibernate中得到了使用。採用版本戳的話,首先需要在你有樂觀鎖的資料庫table上建立乙個新的column,比如為number型,當你資料每更新一次的時候,版本數就會往上增加1.比如同樣有2個session同樣對某條資料進行操作。兩者都取到當前的資料的版本號為1,當第乙個session進行資料更新後,在提交的時候檢視到當前資料的版本還為1,和自己一開始取到的版本相同。就正式提交,然後把版本號增加1,這個時候當前資料的版本為2.

當第二個session也更新了資料提交的時候,發現資料庫中版本為2,和一開始這個session取到的版本號不一致,就知道別人更新過此條資料,這個時候再進行業務處理,比如整個transaction都rollback等等操作。在用版本戳的時候,可以在應用程式側使用版本戳的驗證,也可以在資料庫側採用trigger(觸發器)來進行驗證。不過資料庫的trigger的效能開銷還是比較的大,所以能在應用側進行驗證的話還是推薦不用trigger.

[3]第三種做法和第二種做法有點類似,就是也新增乙個table的column,不過這次這個column是採用timestamp型,儲存資料最後更新的時間。在oracle9i以後可以採用新的資料型別,也就是timestamp with time zone型別來做時間戳。這種timestamp的資料精度在oracle的時間型別中是最高的,精確到微秒(還沒與到納秒的級別),一般來說,加上資料庫處理時間和人的思考動作時間,微秒級別是非常非常夠了,其實只要精確到毫秒甚至秒都應該沒有什麼問題。和剛才的版本戳類似,也是在更新提交的時候檢查當前資料庫中資料的時間戳和自己更新前取到的時間戳進行對比,如果一致則ok,否則就是版本衝突。如果不想把**寫在程式中或者由於別的原因無法把**寫在現有的程式中,也可以把這個時間戳樂觀鎖邏輯寫在trigger或者儲存過程中。

原文出處:

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

expert oracle database architecture學習筆記 悲觀鎖定與樂觀鎖定 第6章.鎖 為了避免丟失更新,要使用某種鎖定策略,共有兩種鎖定策略 悲觀鎖定或樂觀鎖定。悲觀鎖定 pessimistic locking 使用者在螢幕上修改值之前,這個鎖定方法就要起作用。例如,使用者...

oracle 鎖 悲觀鎖與樂觀鎖

總結於ocl程式設計藝術 經常發生的錯誤錯誤 更新丟失,舊資料更新了最新的資料。解決問題的方法 在oracle中看好悲觀鎖 取決於oracle鎖開銷小,高併發 但在其他的資料庫已deprecated 悲觀鎖 在使用者有意執行更新等dml操作之前,就在行上加鎖for update nowait 悲觀鎖...

oracle 悲觀鎖 樂觀鎖

為了得到最大的效能,一般資料庫都有併發機制,不過帶來的問題就是資料訪問的衝突。為了解決這個問題,大多數資料庫用的方法就是資料的鎖定。資料的鎖定分為兩種方法,第一種叫做悲觀鎖,第二種叫做樂觀鎖。什麼叫悲觀鎖呢,悲觀鎖顧名思義,就是對資料的衝突採取一種悲觀的態度,也就是說假設資料肯定會衝突,所以在資料開...