有没有办法可以测试一行是否已被锁定以便在Oracle中进行更新?
select * from SOME_TABLE where THE_ID = 1000 for update;
对于另一个用户,我想检查是否锁定了THE_ID = 1000的行.如果我尝试更新或某些东西,第二个用户被阻止并继续等待(不想这样).
select * from SOME_TABLE where THE_ID = 1000 for update NOWAIT;
由于我不能在同一行上放置两个锁,因此会失败.确实如此.我得到一个“ORA-00054:资源忙,并通过NOWAIT指定的错误获取”.我是否可以始终依靠此错误来检查锁的存在,或者是否有更简单,更清晰的方法来确定行是否被锁定?
谢谢!
解决方法
您可以使用FOR UPDATE NOWAIT编写一个过程,并在该行被锁定时返回错误消息:
sql> CREATE OR REPLACE PROCEDURE do_something(p_id NUMBER) IS 2 row_locked EXCEPTION; 3 PRAGMA EXCEPTION_INIT(row_locked,-54); 4 BEGIN 5 FOR cc IN (SELECT * 6 FROM some_table 7 WHERE ID = p_id FOR UPDATE NOWAIT) LOOP 8 -- proceed with what you want to do; 9 NULL; 10 END LOOP; 11 EXCEPTION 12 WHEN row_locked THEN 13 raise_application_error(-20001,'this row is locked...'); 14 END do_something; 15 / Procedure created
现在让我们用两个会话构建一个小例子:
session_1> select id from some_table where id = 1 for update; ID ---------- 1 session_2> exec do_something(1); begin do_something(1); end; ORA-20001: this row is locked... ORA-06512: at "VNZ.DO_SOMETHING",line 11 ORA-06512: at line 2 session_1> commit; Commit complete session_2> exec do_something(1); PL/sql procedure successfully completed