21

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

4

1 回答 1

31

使用for update nowait将导致行忙碌并获取锁,直到执行提交或回滚。任何其他尝试获取锁的会话都将收到一条 Oracle 错误消息,ORA-00054: resource busy and acquire with NOWAIT specified or timeout expired而不是等待锁释放。

会话1:

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.

于 2012-11-06T09:58:11.590 回答