【问题标题】:How do you check if a row is locked for update?你如何检查一行是否被锁定以进行更新?
【发布时间】:2011-04-26 00:12:16
【问题描述】:

有没有一种方法可以测试某行是否已在 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 指定错误获取”。我是否可以始终依靠此错误来检查锁的存在,或者是否有更简单、更简洁的方法来确定行是否被锁定?

谢谢!

【问题讨论】:

  • 您应该收到此错误“ORA-00054: 资源繁忙并使用 NOWAIT 指定获取” - 您确定您的用户可以看到该表吗?
  • @SeriousCallersOnly:谢谢,我确实遇到了“ORA-00054:资源繁忙,并以 NOWAIT 指定错误获取”。 ORA-00942 是由我的应用程序的另一层抛出的。对于那个很抱歉。我将编辑问题。

标签: sql oracle ora-00054


【解决方案1】:

您可以使用 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

【讨论】:

  • 我已经回复了 SeriousCallersOnly,我确实遇到了 ORA-00054 错误。谢谢你。但是我可以指望它来检查锁吗?
  • @dpb:你可以依赖这个机制。我添加了一个小示例,展示了该过程如何与锁定同一行的两个会话一起工作。
【解决方案2】:

它既不简单也不干净,但信息可在V$LOCKV$SESSION 视图中找到。

但是,如果您觉得需要在您的正常应用程序代码中使用这样的内容,则需要重新考虑。应用程序不应该关心数据库如何锁定。如果遇到死锁,则需要重组查询,以免发生。

【讨论】:

    猜你喜欢
    • 2022-01-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-06-10
    • 2010-09-08
    • 2011-12-05
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多