什么时候我应该在游标中使用'for update nowait'?

时间:2012-11-06 09:39:25

标签: oracle stored-procedures oracle11g oracle10g cursor

在这种情况下,我们需要在游标中使用for update nowait

1 个答案:

答案 0 :(得分:18)

使用for update nowait将导致行忙并获取锁定,直到执行提交或回滚。 尝试获取锁定的任何其他会话都将收到类似ORA-00054: resource busy and acquire with NOWAIT specified or timeout expired instead of waiting the lock to release的Oracle错误消息。

<强> SESSION1:

CURSOR abc_cur 
IS 
select * from dept where deptno =10 for update nowait;

这里的行被锁定,直到游标关闭或执行提交/回滚。同时,如果会话2中的另一个用户尝试访问相同的记录,则会抛出错误,如下所示:

<强>会话2:

select * from dept where deptno =10 for update nowait;

此用户甚至无法更新或删除第一个会话锁定的相同记录。

ERROR at line 1:
`ORA-00054: resource busy and acquire with NOWAIT specified or timeout expired`

<强>用法:  现在,如果您想对某些记录集进行一些操作,并且您不希望其他会话中的其他用户覆盖您的数据,那么您必须先锁定记录(使用for update nowait),然后进行操作。完成操作后,关闭光标并提交。

修改 假设temp中有10行,我在会话1中执行以下脚本:

declare
  cursor abc is select * from temp for update nowait;
  temp abc%rowtype;
begin
  open abc;
  -- do slow stuff here
  close abc;
  commit; 
end;

在会话2中,我在会话1中的脚本仍在运行时执行以下操作

select * from temp;

10 rows found 

如果我在会话2中执行相同的脚本,而会话1中的脚本仍在运行

declare
  cursor abc is select * from temp for update nowait;
  temp abc%rowtype;
begin
  open abc;
  -- do slow stuff here
  close abc;
  commit; 
end;

然后我得到ORA-00054: resource busy and acquire with NOWAIT specified or timeout expired instead of waiting the lock to release.