首页 > 解决方案 > 即使它被用户锁定如何更新表

问题描述

我有一个执行 ap_payment_schedules_all 表更新的集成包。但是,如果任何用户与此表或 ap_invoices_all 保持非活动会话,则并发等待队列执行。我需要使这个并发能够避免这些锁。我应该在我的选择中添加什么?

提前致谢!

下面的事情没有解决:

for update nowait
for update skip locked 

for blah (
select ... from table
union all
select ... from table);

update table 
set a1 = blah.a
where ....;

标签: oracleplsqltransactionslocking

解决方案


除了通过ALTER SYSTEM KILL SESSION '...'.

这让您只有几个选择:

1) 在程序运行时监视数据库,以确保程序没有等待锁。您可以获取有关哪些会话阻止了哪些其他会话的V$SESSION.BLOCKING_SESSION信息V$SESSION.FINAL_BLOCKING_SESSION

如果合适的话,您可以去找 DBA 来终止阻塞会话。显然,您需要确定您正在杀死谁/什么。如果只是一个用户让他们的应用程序打开并回家过夜,那么它可能是安全的。

2)SELECT .. FOR UPDATE WAIT 3在获取要处理的行时使用(或多长时间)。这有时在循环结构中完成,如下所示:

FOR r IN ( SELECT rowid row_id, <other columns> FROM ... WHERE ... ) LOOP
  -- These are the rows we need to process.  Acquire a lock on each one before attempting.
  BEGIN
      SELECT 'x' FROM ... WHERE rowid = r.row_id FOR UPDATE WAIT 3;
      -- If you get here, you have a lock.
      ... processing ...
  EXCEPTION
    -- You'll need to define e_wait_timeout and associate ORA-30006 to it via pragma exception_init...
    WHEN e_wait_timeout THEN
      -- Record that the record was skipped so you can process it later.
  END;
END LOOP;

推荐阅读