Oracle
SQL/PL 中的範例樂觀離線鎖?
唉,ora_rowscn 方法不會很好地工作。它仍然啟用“失去的更新”。
我有來自 AskTom 的資訊:ORA_ROWSCN 用於樂觀鎖定
在此處複製範例以預測死連結…
set echo on drop table t; create table t ( x int primary key, name varchar2(30) ) rowdependencies; insert into t values ( 1, 'john' ); insert into t values ( 2, 'mary' ); commit; variable ora_rowscn number set autoprint on exec select ora_rowscn into :ora_rowscn from t where x = 2; set echo off prompt in another session issue: prompt variable ora_rowscn number prompt set autoprint on prompt exec select ora_rowscn into :ora_rowscn from t where x = 2;; prompt and come back here and hit enter... pause set echo on update t set name = 'beth' where x = 2 and ora_rowscn = :ora_rowscn; set echo off prompt in another session issue: prompt update t set name = 'sally' where x = 2 and ora_rowscn = :ora_rowscn;; prompt and come back here and hit enter... pause commit; set echo off prompt now commit in the other session and notice your lost update :(
恕我直言,您應該在表中添加一個額外的列(例如:Version_Number),您可以在其中設置更新記錄時序列的 nextval(使用觸發器,或在包程式碼中執行此操作)。
工作流:客戶端查詢一些行並獲取帶有 version_Number 的數據。更新此數據時,他需要使用記錄中的目前版本號檢查版本號。如果它們不同,則不會更新任何行,您應該向客戶端返回錯誤 (No_Records_Found)。
create table t ( x int primary key, name varchar2(30), version_Number number); create sequence s_t start with 1 increment by 1; insert into t values ( 1, 'john', s_t.nextval); insert into t values ( 2, 'mary', s_t.nextval); commit; select * from t;
你會看到這樣的東西:
X NAME Version_Number 1 john 1 2 mary 2
.
-- first session update t set name = 'beth', version_number = s_t.nextval where x = 2 and version_number = 2; -- second session update t set name = 'sally', version_number = s_t.nextval where x = 2 and version_number = 2; -- First session commit; -- Second session returns with no updated records...
正如我所說,您應該通知客戶沒有更新記錄,但這可能有兩個原因:
- 過時的記錄
- 刪除記錄
在這兩種情況下,客戶端都必須再次刷新此記錄並確定下一步要做什麼。