[英]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$LOCK
和V$SESSION
視圖中找到相關信息。
但是,如果您覺得需要使用此類內容作為正常應用程序代碼的一部分,則需要再次考慮。 應用程序不應該關心數據庫如何鎖定。 如果您遇到死鎖,則需要重新構建查詢,以免發生這些問題。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.