Decode360's Blog

业精于勤而荒于嬉 QQ:150355677 MSN:decode360@hotmail.com

  BlogJava :: 首页 :: 新随笔 :: 联系 ::  :: 管理 ::
  397 随笔 :: 33 文章 :: 29 评论 :: 0 Trackbacks
锁的查询及解锁
 
    Oracle中的锁的功能很多,当然锁的属性不单是Oracle中所独有的,而是在DBMS中的基础特性所规定的。也就是说无论使用何种DBMS,其S、X、SX等锁的基本属性都是一致的。只是各自的实现形式上的差别。当然每个DBMS在内部实现上都会所不同,Oracle在这方面具有极大的优势。关于这一点,可以参见Tom的《9i&10g Programming Techniques And Solutions》。下面介绍一下:
 
一、死锁
 
    死锁是指:两个事务同时希望锁定已经被另一事务锁定的数据,而形成的互相等待的情况。
 
    举例:
 
    SQL-1> lock table t1 in exclusive mode; --session1对t1表加X锁
 
    Table(s) Locked.
 
    SQL-2 > lock table t2 in share mode;--session2对t2表加S锁
 
    Table(s) Locked.
 
    SQL-1> lock table t2 in exclusive mode; --session1对t2表加X锁,等待
 
    SQL-2 > lock table t1 in share mode;--session2对t1表加S锁,等待
 
    SQL-1>
               *
    ERROR at line 1:
    ORA-00060: deadlock detected while waiting for resource
    -- 最终session1中报错产生死锁
 
    注:Oracle系统会自动、有效地对死锁进行检测,当检测到死锁后会选择一个事务退出,而另一个事务继续。
 
 
    遇到死锁时,事务接到报错也不会自动回滚,而是继续等待,所以只有另一个事务用户提交,或者杀死进程才能最终解锁。
 
 
二、锁的查询
 
    可以通过动态表v$lock和v$locked_object来查看当前锁的情况,具体表结构:
 
 
SQL> desc v$lock
Name    Type        Comments
------- ----------- -------------------------
ADDR    RAW(4)      在内存中锁定的对象的地址
KADDR   RAW(4)      在内存中锁的地址
SID     NUMBER      SESSION标识
TYPE    VARCHAR2(2) 锁类型:TX=行锁或事务锁;TM=表锁或DML锁;UL=PL/SQL用户锁
ID1     NUMBER      锁的第1标识号。TM-将要被锁定的对象标识号;TX-撤销段号码的十进制值
ID2     NUMBER      锁的第2标识号。TM-0;TX-交换次数
LMODE   NUMBER      锁的模式:0None;1Null;2RS;3RX;4S;5SRX;6X
REQUEST NUMBER      会话申请的锁的模式,与LMODE中的模式相同
CTIME   NUMBER      已持有或等待锁的时间,以秒为单位
BLOCK   NUMBER      当前锁是否阻塞另一个锁。0不阻塞;1阻塞
 
可以通过和v$session表关联,找出某个用户的锁。
 
 
SQL> desc v$locked_object
Name            Type         Comments
--------------- ------------ -------------------------
XIDUSN          NUMBER       回滚段号码
XIDSLOT         NUMBER       被锁定的对象在撤销段中的位置
XIDSQN          NUMBER       序列号
OBJECT_ID       NUMBER       被锁定的对象的标识号
SESSION_ID      NUMBER       持有锁的session标识号
ORACLE_USERNAME VARCHAR2(30) 持有锁的用户ID
OS_USER_NAME    VARCHAR2(30) 持有所的操作系统ID
PROCESS         VARCHAR2(12) 操作系统进程号
LOCKED_MODE     NUMBER       锁模式0None;1Null;2RS;3RX;4S;5SRX;6X

同理,可以关联dba_objects表,来查找某个表现有的锁。
 
 
SQL> desc dba_locks
Name            Type         Comments
--------------- ------------ -------------------------
SESSION_ID      NUMBER       保持或申请锁的session标识号
LOCK_TYPE       VARCHAR2(26) 锁的类型,同v$lock.type
MODE_HELD       VARCHAR2(40) 保持的锁的模式
MODE_REQUESTED  VARCHAR2(40) 申请的锁的模式
LOCK_ID1        VARCHAR2(40) 锁的第1标识号
LOCK_ID2        VARCHAR2(40) 锁的第2标识号
LAST_CONVERT    NUMBER       已持有或等待锁的时间,以秒为单位
BLOCKING_OTHERS VARCHAR2(40) 当前锁是否阻塞另一个锁。Not Blocking不阻塞;Blocking阻塞
 
这个表基本等同于v$lock
 
 
SQL> desc dba_waiters
Name            Type         Comments
--------------- ------------ -------------------------
WAITING_SESSION NUMBER       等待锁(被阻塞)的session标识号
HOLDING_SESSION NUMBER       保持锁(正阻塞)的session标识号
LOCK_TYPE       VARCHAR2(26) 锁的类型
MODE_HELD       VARCHAR2(40) 保持的锁的模式
MODE_REQUESTED  VARCHAR2(40) 申请的锁的模式
LOCK_ID1        NUMBER       锁的第1标识号
LOCK_ID2        NUMBER       锁的第2标识号
 
这个表是比较重要的,可以看出是哪些在等待的锁影响了系统
 
 
SQL> desc dba_blockers
Name            Type   Comments
--------------- ------ -------------------------
HOLDING_SESSION NUMBER 阻塞了其他session的那些session标识号
 
 
 
三、解锁
 
-----------------------------------------------------------------------------
由sys用户通过查询与锁相关的视图来了解锁,了解阻塞会话与被阻塞会话的sid、serial#、
用户名及其所使用的DML操作语句。
-----------------------------------------------------------------------------
 
set pagesize 40 linesize 150
column blockers format a45
column waiters format a45
select '阻塞者('||sb.sid||':'||sb.serial#||'-'||sb.username||')-'||qb.sql_text blockers,
       '等待者('||sw.sid||':'||sw.serial#||'-'||sw.username||')-'||qw.sql_text waiters
from v$lock lb,v$lock lw,v$session sb,v$session sw,v$sql qb,v$sql qw
where lb.sid=sb.sid
  and lw.sid=sw.sid
  and sb.prev_sql_addr=qb.address
  and sw.sql_address=qw.address
  and lb.id1=lw.id1
  and sb.lockwait is null
  and sw.lockwait is not null
  and lb.block=1;

---------------------------------------------------------------------------
要了解哪些数据库用户的会话锁定了对象、锁定的模式是什么、对应的操作系统
用户是在哪台计算机上进行操作的、被锁定的对象及其类型等信息
---------------------------------------------------------------------------
set pagesize 40 linesize 150
column username format a9
column sid format 9999
column serial# format 99999999
column mode_locked format a12
column os_user_name format a16
column object_name format a12
column object_type format a12
select s.username,s.sid,s.serial#,
     decode(lo.locked_mode,
     0,'none',
     1,'null',
     2,'row-s(ss)',
     3,'row-x(sx)',
     4,'share',
     5,'s/row-x(ssx)',
     6,'exclusive',
     to_char(lo.locked_mode)) mode_locked,
     lo.os_user_name,
     do.object_name,do.object_type
from v$session s,v$locked_object lo,dba_objects do
where
   lo.object_id=do.object_id;

---------------------------------------------------------------------------
要了解阻塞者会话的sid、serial#信息
---------------------------------------------------------------------------
set pagesize 40 linesize 150
column username format a9
column sid format 9999
column serial# format 99999999
select s.username,s.sid,s.serial#
from v$session s,dba_blockers dbab
where s.sid=dbab.holding_session;
 
---------------------------------------
解锁     
---------------------------------------
alter system kill session 'sid,serial#';
 
-----------------------------------------------------------
declare
cursor cur_lock IS
select sid,type,lmode,request,ctime,block from v$lock;
mysid v$lock.sid%type;
mytype v$lock.type%type;
mylmode v$lock.lmode%type;
myrequest v$lock.request%type;
myctime v$lock.ctime%type;
myblock v$lock.block%type;
icount integer;
begin 
open cur_lock;
loop
fetch cur_lock into mysid,mytype,mylmode,myrequest,myctime,myblock;
   exit when cur_lock%NOTFOUND;
   select count(*) into icount from v$lock where sid=mysid;
   if icount>0 then
   insert into lock_test (sid,type,lmode,request,ctime,block) values
   (mysid,mytype,mylmode,myrequest,myctime,myblock);
   else 
     dbms_output.put_line('no data');
   end if;
end loop;
close cur_lock;
EXCEPTION
  WHEN OTHERS THEN
RAISE_APPLICATION_ERROR(-20000,'ERROR trg_pets_upper_pet_kind: '|| SQLERRM);
end;
/
 
 
posted on 2008-10-27 20:38 decode360 阅读(122) 评论(0)  编辑  收藏 所属分类: 07.Oracle

只有注册用户登录后才能发表评论。


网站导航: