我有一个集成包,用于执行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 ....;
答案 0 :(得分:0)
除了通过ALTER SYSTEM KILL SESSION '...'
杀死另一个用户的会话外,没有其他方法可以破坏Oracle中另一个用户的锁定。
剩下的只有几个选择:
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;
答案 1 :(得分:-1)
一旦获得了锁,就无法更新