簡體   English   中英

如何檢查行是否被鎖定以進行更新?

[英]How do you check if a row is locked for update?

有沒有辦法可以測試一行是否已被鎖定以便在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

它既不簡單也不干凈,但可以在V$LOCKV$SESSION視圖中找到相關信息。

但是,如果您覺得需要使用此類內容作為正常應用程序代碼的一部分,則需要再次考慮。 應用程序不應該關心數據庫如何鎖定。 如果您遇到死鎖,則需要重新構建查詢,以免發生這些問題。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM