SELECT ... FOR UPDATE SKIP LOCKED;

jane_pop發表於2014-10-24
請求鎖定需要排隊。如果某個會話請求一個鎖定,但由於其他會話已經鎖定好了指定行或物件兒無法獲得所需的鎖定,那麼這個會話將會等待。此時,可能有多個會話都在等待訪問相同的記錄或物件,在這種情況下,oracle會跟蹤這些會話請求鎖定的順序。當使用鎖定的會話解除鎖定時,下一個會話就會獲得授權,以此類推,這種機制被稱為“排隊enqueue”機制。
如果不希望某個會話在無法獲取鎖定的時候進行排隊,那麼避免排隊的唯一方式是使用SELECT ...FOR UPDATE命令的WAIT或
NOWAIT子句。因為SELECT語句並不需要任何鎖定,所以普通的SELECT 語句可以成功地執行。但是,DML語句則會被掛起。
SELECT... FOR UPDATE命令會採用排他模式來選擇和鎖定記錄。如果某行已經被鎖定,那麼在鎖定被釋放之前,SELECT ... FOR UPDATE語句會像DML語句一樣進行排隊並掛起會話。使用SELECT ...FOR UPDATE NOWAIT或
SELECT ... FOR UPDATE WAIT就可以避免掛起會話,其中是以秒為單位的數值。使用SELECT ... FOR UPDATE選項中的
一個獲得鎖定之後,我們就可以在不必掛起會話的情況下執行DML命令。

開啟一個會話,向表t插入一條記錄並提交:
HR@orcl 23-OCT-14>insert into t values(1); 

1 row created. 

HR@orcl 23-OCT-14>commit; 

Commit complete. 

使用select...for update子句:
HR@orcl 23-OCT-14>select * from t for update; 

ID 
---------- 
1


開啟另一個會話,同樣執行select * from t for update;
HR@orcl 23-OCT-14>select * from t for update;

該回話就會被掛起。
當一個會話在一個物件上使用語句select ... for update;時,另一個會話也在同一個物件上執行select ... for update;就會被掛起。
要等到第一個會話提交或者回滾之後,第二個會話才可以繼續:
HR@orcl 23-OCT-14>commit; 

Commit complete.

第二個會話:
HR@orcl 23-OCT-14>select * from t for update; 

ID 
---------- 
1

但是如果我們使用的是select ... for update nowait;的話,另一個會話就不會被掛起,而是會直接返回一個ORA-00054的錯誤,同時也可以告訴別人,我正在改著,你要等等:

HR@orcl 23-OCT-14>select * from t for update nowait; 

ID 
---------- 
1

第二個會話:
HR@orcl 23-OCT-14>select * from t for update nowait; 
select * from t for update nowait 

ERROR at line 1: 
ORA-00054: resource busy and acquire with NOWAIT specified or timeout expired


另外,可以將關鍵字SKIP LOCKED 附加到SELECT FOR UPDATE語句後,這樣將返回且鎖定並未由另一個會話鎖定的行。早期的版本中就存在此命令,但從11g開始才對其進行支援。
在第一個會話中向表t插入第二條記錄並提交:
HR@orcl 23-OCT-14>insert into t values(2); 

1 row created. 

HR@orcl 23-OCT-14>commit; 

Commit complete. 

HR@orcl 23-OCT-14>select * from t; 

ID 
---------- 

2


HR@orcl 23-OCT-14>select * from t where id=1 for update; 

ID 
---------- 
1
此時第一條記錄已經被鎖定了。

在第二個會話中執行:
HR@orcl 23-OCT-14>select * from t for update skip locked; 

ID 
---------- 
2

透過這個命令我們可以看到表t中沒有被鎖定的第二條記錄了。












來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/29800581/viewspace-1308866/,如需轉載,請註明出處,否則將追究法律責任。

相關文章