pessimistic鎖定對(duì)optimistic鎖定(2)
2024-07-21 02:34:20
供稿:網(wǎng)友
pessimistic locking 考慮 1) 使用select for update(nowait)不像optimistic locking需要用戶額外的編碼,實(shí)現(xiàn)簡(jiǎn)單。 2) 在交互式應(yīng)用中,行鎖的時(shí)間可能較長(zhǎng)。假如用戶所住該紀(jì)錄后,離開終端,則其他用戶將無法更新該紀(jì)錄(但用戶可以查看該記錄,Oracle 寫并不阻塞讀)。在“有線“(服務(wù)器可以知道客戶端的狀態(tài))應(yīng)用中,應(yīng)用保留著客戶端的session,可以通過數(shù)據(jù)庫或者應(yīng)用服務(wù)器設(shè)置session的idle time,假如客戶端長(zhǎng)時(shí)間占有資源且不做操作,則斷掉該連結(jié),釋放鎖。但在“無線”(服務(wù)器無法知道客戶端的狀態(tài))應(yīng)用中,則無法設(shè)置idle time斷掉客戶端。 3) UI交互。假如紀(jì)錄已經(jīng)被其他用戶鎖住,當(dāng)前用戶在修改紀(jì)錄之前就會(huì)獲知,可以選擇等待或者取消等待。 optimistic locking策略 因?yàn)樵诟聰?shù)據(jù)前,讀取數(shù)據(jù)的時(shí)候不鎖紀(jì)錄,所以要在更新紀(jì)錄的時(shí)候,驗(yàn)證紀(jì)錄是否已經(jīng)被修改過;這需要額外的代碼和設(shè)計(jì)。常用的方法包括1)整合所有相關(guān)列驗(yàn)證2)使用timestamp時(shí)間戳驗(yàn)證。 整合所有相關(guān)列驗(yàn)證 Time1: Ian read SHERSA’s salary record:
SQL> select * from emp where name=' SHERSA ' ; ID NAME SALARY ---------- ------------------------- ---------- 8 SHERSA 3000
Time2: HR read SHERSA’s salary record:
SQL> select * from emp where name=' SHERSA ' ; ID NAME SALARY ---------- ------------------------- ---------- 8 SHERSA 3000
Time3: Ian update SHERSA’s salary by increment 500 SQL> update emp set salary=3500 where id=8 and name=' SHERSA ' and salary=3000; SQL> commit; SQL> select * from emp where name='SHERSA'; ID NAME SALARY ---------- ------------------------- ---------- 8 SHERSA 3500 Time4: HR update SHERSA’s salary SQL SQL> update emp set salary=salary*1.05 where id=8 and name=' SHERSA ' and salary=3000; 0 rows updated. 顯示0行被更新了,表示紀(jì)錄被其他用戶有效修改(無效修改指其他用戶雖然修改過,但數(shù)值沒有變)過;可以通過程序判定,提示用戶“其他用戶已經(jīng)修改過,請(qǐng)?jiān)俅翁峤荒愕男薷恼?qǐng)求….”. 顯然,這個(gè)方法需要所有的驗(yàn)證列都在where語句中,開發(fā)的時(shí)候不夠靈活。 使用timestamp時(shí)間戳驗(yàn)證 在每個(gè)表中增加一個(gè)timestamp字段,更新時(shí)候驗(yàn)證timestamp字段。 SQL> Alter table emp add mofied current_timestamp default (current_timestamp) not null; 增加一個(gè)timestamp字段,標(biāo)記該紀(jì)錄改動(dòng)的時(shí)間 SQL> create or replace trigger upd_modified_emp_tri 2 before update on emp for each row
3 begin 4 :new.modified:=current_timestamp; 5 end; 6 / Trigger created. 建立必要的觸發(fā)器 Time1: Ian read SHERSA’s salary record: SQL> select * from emp where id=14;
ID NAME SALARY MODIFIED ---------- -------------------- ---------- --------------------- 14 SHERSA 3000 15-DEC-05 06.34.19.126861 AM
Time2: HR read SHERSA’s salary record:
SQL> select * from emp where id=14;
ID NAME SALARY MODIFIED ---------- -------------------- ---------- --------------------- 14 SHERSA 3000 15-DEC-05 06.34.19.126861 AM
Time3: Ian update SHERSA’s salary by increment 500 SQL> update emp set salary=3500 where id=14 and modified=to_timestamp('15-DEC-05 06.34.19.126861 AM'); 1 row updated. SQL> commit; SQL> select * from emp where id=14;
ID NAME SALARY MODIFIED ---------- -------------------- ---------- --------------------- 14 SHERSA 3500 15-DEC-05 06.35.39.585907 AM
Time4: HR update SHERSA’s salary SQL> update emp set salary=salary*1.05 where id=14 and modified=to_timestamp('15-DEC-05 06.34.19.126861 AM'); 0 rows updated. 顯示0行被更新了,表示紀(jì)錄被其他用戶修改;可以通過程序判定,提示用戶“其他用戶已經(jīng)修改過,請(qǐng)?jiān)俅翁峤荒愕男薷恼?qǐng)求….”. 與第一種方法相比,where部分只需要增加額外的字段timestamp字段即可。低于9i的版本可以自定義驗(yàn)證列。 optimistic locking考慮 optimistic locking需要用戶額外的編碼和設(shè)計(jì),比pessimistic復(fù)雜。 2) 在交互式應(yīng)用中,行鎖的時(shí)間較短,僅僅在更新紀(jì)錄的時(shí)候獲得。讀記錄時(shí)候不獲得鎖,用戶操作的時(shí)候離開終端,則其他用戶仍然可以更新該紀(jì)錄。在“無線”應(yīng)用中,通常使用optimistic locking。 3) UI交互。假如紀(jì)錄已經(jīng)被其他用戶修改,用戶費(fèi)了很多精力和時(shí)間去填寫表格,點(diǎn)擊[提交],結(jié)果系統(tǒng)返回[更新0行,請(qǐng)重新填寫],然后系統(tǒng)重新load新紀(jì)錄的表格,用戶之前輸入的改動(dòng)都將不再記憶。 Reference:
/ArtImage/20060802/locking.pdf
lost update http://asktom.oracle.com/pls/ask/f?p=4950:8:14381454400784279997::NO::F4950_P8_DISPLAYID,F4950_P8_CRITERIA:30562552526857