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