表A  (id  number,b_id  number,detail  varchar2(100))  
其中b_id  是外部关键字,id是主关键字  
表B  (id  number)  
其中id是主关键字  
 
 
有如下测试记录  
insert  into  b  (id)  values  (1);  
insert  into  b  (id)  values  (2);  
insert  into  b  (id)  values  (3);  
insert  into  b  (id)  values  (4);
insert  into  b  (id)  values  (5);  
commit;  
insert  into  a  (id,b_id,detail)  values  (1,2,'test');  
insert  into  a  (id,b_id,detail)  values  (2,3,'test');  
insert  into  a  (id,b_id,detail)  values  (3,2,'test');  
insert  into  a  (id,b_id,detail)  values  (4,1,'test');  
commit;  
 
 
现在在session1中通过procedure中实现update  a  set  b_id=b_id+2  where  id<=2操作  
如果有另外一个session2执行delete  from  b  where  id>=4操作  
 
如果这两个session并发,且session1早于session2开始,晚于session2结束,关键是update操作晚于delete操作。  
怎样通过RS锁保障session1的执行从而使得session2失败。

解决方案 »

  1.   

    session1中如果能够在一开始就对B表的ID IN (4,5)进行锁定,这样session2就失败。
      

  2.   

    已经建了外键的。由于a表的b_id一开始就只有1,2,3三个值,所以delete的操作时可以成功的
      

  3.   

    我用你上面的测试数据,当session1执行update但没有commit前,session2执行delete时是被锁住的,session1执行commit后,session2就会出现“ORA-02292: 违反完整约束条件 (TEST.FK_T_A) - 已找到子记录日志”错误。
      

  4.   

    sorry,没看清你的需求,session1执行update是迟于session2的delete。
      

  5.   

    如果存储过程中明确知道需要锁住b表的哪些id,可以在存储过程的开始用动态sql执行'select * from B where id in(...) for update'
      

  6.   

    呵本来select for update可以锁住,但是在存储过程中必须select into from for update才行,有没有别的方法?lock table [table_name] in row share mode; 这个只是意向锁,如果对应行没有涉及到DML操作,session2依然是可以删除的。
      

  7.   

    总不至于为了锁行,不断的用select into吧
      

  8.   

    用动态sql。execute immediate 'select * from ... for update';