在这种情况下,我们需要for update nowait
在游标中使用。
1 回答
使用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.