DB排他的处理方法

 

1.通过FOR UPDATE进行排他

      ①记录在修改之前先给它上锁,即:使用SELECT语句将要修改的记录取出来,并且在sql末加上“FOR UPDATE WAIT timeout时间”(SELECT ・・・ FOR UPDATE WAIT timeout时间)

见用户A的操作过程:

DB排他的处理方法_第1张图片

当其他用户想要修改这条记录时,发现这条记录被人上了锁,程序就会报错。

 

 

见用户B操作过程:

DB排他的处理方法_第2张图片

 

 

2.通过“修改时间”进行的排他处理

①在点击详细取得被修改数据详细内容时,取得该记录在数据库中的“修改时间”(或更新次数),我们称它为“修改时间1”。

②在点击确认进行正式修改时,再次从数据库中取得要修改记录的“修改时间”(或更新次数),我们称它为“修改时间2”。

   然后比较“修改时间1”和“修改时间2”:

   如果2者相等,则进行正常的修改操作,并将系统的当前时间写入该记录的“修改时间”字段。

   如果发现2者不相等,说明该记录已经被他人修改了,程序就报错。

 

 

 

 

 

 

3.其实上述两种方法都有弊端,第一种方法的弊端是,如果一个用户锁定数据的时间比较长,那么其它用户将要等待很长时间;第二种方法的弊端是,如果两个用户“同时”更新数据的,那么数据库将无法判断到底要更新哪一个用户的请求。

比较好的做法是把两种方法结合起来。

①在点击详细取得被修改数据详细内容时,取得该记录在数据库中的“修改时间”,我们称它为“修改时间1”。

②在点击确认进行正式修改时,再次从数据库中取得要修改记录的“修改时间”,我们称它为“修改时间2”。

然后比较“修改时间1”和“修改时间2”:

如果2者相等,则进行正常的修改操作,并将系统的当前时间写入该记录的“修改时间”字段。

记录在修改之前先给它上锁,即:使用SELECT语句将要修改的记录取出来,并且在sql末加上“FOR UPDATE WAIT timeout时间” (SELECT ・・・ FOR UPDATE WAIT timeout时间)

对该条记录进行修改。修改完成,开锁。

如果发现2者不相等,说明该记录已经被他人修改了,程序就报错。

 

 

 

 

 

例子:以更新次数为例

详细画面初期化时取得更新次数

 select upcount from table where key=?

如结果6,放于页面隐藏控件中

 

点提交按钮在数据库操作前,进行比较,并且锁定数据

select upcount from table where key=? and upcount =6 for update wait 5

 

如果2者相等修改数据

update table set item=?, upcount=upcount+1 where key=? and upcount=6

commit;

 

 

 

4、在oracle10g 中可以用ORA_ROWSCN 函数代替“更新次数”,ORA_ROWSCN是根据系统最后更新时间来进行计算。这个ORA_ROWSCN。在默认情况下是采用数据块为单位的,也就是一个数据库块(block)上共享一个ORA_ROWSCN,当数据更新的时候,这个block快的ORA_ROWSCN就会自动更新。所以在默认情况下的话,有可能出现假冲突的情况。比如A,B,C,D四条数据都在一个block上,这个时候A数据更新了,ORA_ROWSCN也会更新,这个时候因为ABCD四条数据存储在一个block上,所以BCD的ORA_ROWSCN也更新过了,其实BCD三条数据并没有更新过,这个就造成了假更新的情况出现。

利用Oracle 9i提供的ROWDEPENDENCIES建表关键字可以解决上面的问题。这个关键字在Oracle9i中是为了增加行依赖性跟踪特性的,支持推进复制。在Oracle10g中有可以用来做行级别的ORA_ROWSCN用了。用这个关键字建表以后,在每行会增加一个隐藏的COLUMN,所以每行会增加6个byte的开销。

这样做的好处是不用再增加一个额外的域,而是由Oracle的ORA_ROWSCN来维护数据,数据开销不是很大,并且减少了出错的可能。缺点就是要重新建表。

 

create table test(id number(10),  ....) ROWDEPENDENCIES

修改前的 ORA_ROWSCN  的值

select id ,ORA_ROWSCN from test

修改数据

update test set name = name || to_char(id) where id = 1 ;

 

修改后的 ORA_ROWSCN 的值

select id ,ORA_ROWSCN from test

只有第一行的数据的 ORA_ROWSCN 改变了,其它行未改变。

 

 

 

 

 

 

 

 

 

 

你可能感兴趣的:(DB排他的处理方法)