BLOCKING

The five common DML statements that willblock in the database are INSERT, UPDATE,DELETE.MERGE and SELECT FOR UPDATE.

 

The solution to a blocked SELECT FOR UPDATEis trivial: simply add the NOWAIT clause and it will no longer block. Instead,your application will report back to the end user that the row is alreadylocked.

 

INSERTS的阻塞通常發生在允許終端用戶生成主鍵或者唯一性列值的時候,比較簡單的避免這種情況發生的辦法是用SEQUENCE來生成主鍵或者唯一性列值。如果不能使用SEQUENCE的話,可以使用手動的鎖,通過DBMS_LOCK包。

 

ORACLE有無限的ROW-LEVEL locking,但是有有限的enqueue locks.

要將執行DBMS_LOCK的權限賦給用戶(SCHEMA)

SQL> grant execute on dbms_lock to ops;

授權成功。

SQL> create or replace trigger demo_bifer
  2  before insert on demo
  3  for each row
  4  declare
  5     l_lock_id       number;
  6     resource_busy   exception;
  7     pragma exception_init( resource_busy,-54);
  8  begin
  9     l_lock_id :=
 10             dbms_utility.get_hash_value (to_char( :new.x),0,1024);
 11     if(dbms_lock.request
 12                             (id     => l_lock_id,
 13                             lockmode=> dbms_lock.x_mode,
 14                             timeout => 0,
 15                             release_on_commit => TRUE) <> 0 )
 16     then
 17             raise resource_busy;
 18     end if;
 19  end;
 20  /

觸發器已創建

在一個session下執行
SQL> insert into demo values (1);

已創建 1 行。


換另一個session下

SQL> insert into demo values (1);
insert into demo values (1)
            *
ERROR 位於第 1 行:
ORA-00054: 資源正忙,要求指定 NOWAIT
ORA-06512: 在"OPS.DEMO_BIFER", line 14
ORA-04088: 觸發器 'OPS.DEMO_BIFER' 執行過程中出錯


發佈了82 篇原創文章 · 獲贊 2 · 訪問量 10萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章