【发布时间】:2012-10-26 05:47:07
【问题描述】:
在什么情况下我们需要在游标中使用for update nowait。
【问题讨论】:
标签: oracle stored-procedures oracle11g oracle10g database-cursor
在什么情况下我们需要在游标中使用for update nowait。
【问题讨论】:
标签: oracle stored-procedures oracle11g oracle10g database-cursor
使用for update nowait 将导致行忙碌并获取锁,直到执行提交或回滚。
任何其他尝试获取锁的会话都将收到类似 ORA-00054: resource busy and acquire with NOWAIT specified or timeout expired 的 Oracle 错误消息,而不是等待锁释放。
会话 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.
【讨论】: