在Oracle中是否有跳过锁定更新的任何替代方法

时间:2019-01-10 06:38:41

标签: oracle plsql oracle11g

我表中有5行。并且某些行在某些会话中被锁定。
我不想产生任何错误,只想等到任何行变为空闲以进行进一步处理

我厌倦了没有等待并跳过锁定:-

  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;

2 个答案:

答案 0 :(得分:0)

为什么不只将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行,其中之一被锁定,那么选择将不会读取此行。那就是为什么当所有数据都被锁定时,它的抛出错误,因为什么都不能跳过。我想这不是您想要的方案。

答案 1 :(得分:0)

听起来您需要考虑事务控制。

如果您在事务中进行工作,则意味着该工作单元需要完成才能生效。 您的意思是,我的更新事务中的某些工作不需要完成即可提交事务。

不仅如此,而且您有两个事务同时运行,并对同一个对象执行操作。本身可能是有效的,但 如果是,那么您真的需要回到第一句话,仔细考虑事务控制和流程,看看是否有办法可以让第二个事务只尝试更新第一个事务中未更新的行