阻塞 之Insert 现象与解决方案

阻塞 之Insert 现象与解决方案
insert阻塞不常见,对于带主键的表,如果表上有唯一约束,有两个会话试图插入相同主键值的一条记录,则其中一个会话会发生阻塞,直到另一个会话提交或回滚。
mld @ORCL >   create   table  demo ( x  int   primary   key  );

表已创建。

mld
@ORCL >   insert   into  demo  values  (  1  );

已创建 
1  行。

----- session2
mld
@ORCL >   insert   into  demo  values  (  1  );

--waiting。。。。。。。。

解决:
    a,使主键保证唯一,可采用UUID,SEQUENCE等方式;
    b,使用DBMS_LOCK.REQUEST根据主键ID的hash值分配一个排它锁,一次只有一个会话能请求成功,见代码:
  
mld @ORCL >  conn sys / mld  as  sysdba
已连接。
sys
@ORCL >   grant   execute   on  dbms_lock  to  mld;

授权成功。
mld
@ORCL >   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    /

触发器已创建

mld
@ORCL >  show error;
没有错误。
mld
@ORCL >   insert   into  demo  values  (  1  );

已创建 
1  行。

--session 
2
mld
@ORCL >   insert   into  demo  values  (  1  );
insert   into  demo  values  (  1  )
*
第 
1  行出现错误:
ORA
- 00054 : 资源正忙, 但指定以 NOWAIT 方式获取资源
ORA
- 06512 : 在 "MLD.DEMO_BIFER", line  14
ORA
- 04088 : 触发器  ' MLD.DEMO_BIFER '  执行过程中出错


mld
@ORCL >

你可能感兴趣的:(阻塞 之Insert 现象与解决方案)