Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1996978
  • 博文数量: 1647
  • 博客积分: 80000
  • 博客等级: 元帅
  • 技术积分: 9980
  • 用 户 组: 普通用户
  • 注册时间: 2008-10-13 15:15
文章分类

全部博文(1647)

文章存档

2011年(1)

2008年(1646)

我的朋友

分类:

2008-10-28 17:53:30

    pessimistic locking 考虑

    1) 使用select for update(nowait)不像optimistic locking需要用户额外的编码,实现简单。

    2) 在交互式应用中,行锁的时间可能较长。如果用户所住该纪录后,离开终端,则其他用户将无法更新该纪录(但用户可以查看该记录,oracle 写并不阻塞读)。在“有线“(可以知道客户端的状态)应用中,应用保留着客户端的session,可以通过数据库或者应用设置session的idle time,如果客户端长时间占有资源且不做操作,则断掉该连结,释放锁。但在“无线”(服务器无法知道客户端的状态)应用中,则无法设置idle time断掉客户端。

    3) UI交互。如果纪录已经被其他用户锁住,当前用户在修改纪录之前就会获知,可以选择等待或者取消等待。

    optimistic locking策略

    因为在更新数据前,读取数据的时候不锁纪录,所以要在更新纪录的时候,验证纪录是否已经被修改过;这需要额外的代码和设计。常用的方法包括1)整合所有相关列验证2)使用timestamp时间戳验证。

    整合所有相关列验证

    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行被更新了,表示纪录被其他用户有效修改(无效修改指其他用户虽然修改过,但数值没有变)过;可以通过程序判断,提示用户“其他用户已经修改过,请再次提交你的修改请求….”.

    显然,这个方法需要所有的验证列都在where语句中,开发的时候不够灵活。

    使用timestamp时间戳验证

    在每个表中增加一个timestamp字段,更新时候验证timestamp字段。

    SQL> Alter table emp add mofied current_timestamp default (current_timestamp) not null;

    增加一个timestamp字段,标记该纪录改动的时间

    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.

    建立必要的触发器

    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行被更新了,表示纪录被其他用户修改;可以通过程序判断,提示用户“其他用户已经修改过,请再次提交你的修改请求….”.

    与第一种方法相比,where部分只需要增加额外的字段timestamp字段即可。低于9i的版本可以自定义验证列。

    optimistic locking考虑

    optimistic locking需要用户额外的编码和设计,比pessimistic复杂。

    2) 在交互式应用中,行锁的时间较短,仅仅在更新纪录的时候获得。读记录时候不获得锁,用户操作的时候离开终端,则其他用户仍然可以更新该纪录。在“无线”应用中,通常使用optimistic locking。

    3) UI交互。如果纪录已经被其他用户修改,用户费了很多精力和时间去填写表格,点击[提交],结果系统返回[更新0行,请重新填写],然后系统重新load新纪录的表格,用户之前输入的改动都将不再记忆。

    Reference:
   
    lost update

【责编:Amy】

--------------------next---------------------

阅读(204) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~