首页 > 解决方案 > 在 oracle 中是否有跳过锁定更新的替代方法

问题描述

我在表中有 5 行。并且某些行在某些会话中被锁定。
我不想产生任何错误,只是想等到任何行都可以自由进行进一步处理

我厌倦了 nowait 并跳过锁定:-

  1. nowait ,但是 nowait 有问题。查询已经写在游标中,当我在游标下使用“nowait”时,查询将返回 null 并且控制将通过说资源繁忙而出错

  2. 我尝试使用更新锁定跳过锁定 - 但是如果表包含 5 行并且所有 5 行都被锁定,那么它会给出错误。

CURSOR cur_name_test IS SELECT def.id , def.name FROM def_map def WHERE def.id = In_id FOR UPDATE skip locked;

标签: oracleplsqloracle11g

解决方案


为什么不只使用 select 进行更新?以下内容正在 plsql 开发人员中进行本地测试。

在第一次会议中,我执行以下操作

SELECT id , name
  FROM ex_employee
   FOR UPDATE;

在第二次会议中,我运行以下但它挂起。

SET serveroutput ON size 2000
/
begin
declare curSOR cur_name_test IS
SELECT id , name
  FROM ex_employee
 WHERE id = 1
   FOR UPDATE ;

begin
for i in cur_name_test loop
      dbms_output.put_line('inside cursor');

end loop;

end;
end;
/
commit
/

当我在第一个会话中提交时,锁将被释放,第二个会话将完成它的工作。我猜你想要,无限等待。

然而,这种锁定机制(悲观锁定)如果管理不当(第一个会话等待第二个会话,第二个会话等待第一个会话),可能会导致死锁。

至于 nowait 错误资源繁忙是正常的,因为您说查询不要等待,如果有锁定。您可以改为等待 30,这将等待 30 秒然后输出错误,但这不是您想要的(我猜)。

至于跳过锁定,选择将跳过锁定的数据,例如您有 5 行,其中一个被锁定,则选择不会读取该行。这就是为什么当所有数据都被锁定时,它会抛出错误,因为什么都不能跳过。我想这不是你想要的。


推荐阅读