• 锁的查询及解锁


    死锁
     
        死锁是指:两个事务同时希望锁定已经被另一事务锁定的数据,而形成的互相等待的情况。
     
        举例:
     
        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;
    /
     
     
    http://www.blogjava.net/wxqxs/archive/2008/10/27/239056.html 



    -The End-

  • 相关阅读:
    C# where用法解析
    C# 判断两张图片是否一致,极快速
    C# 文件过滤器filter
    C# 获取Image图片格式
    C# 中base和this关键字
    C# Http访问帮助类,支持get post请求文件下载 [
    C# 最小化到托盘,托盘右击菜单显示
    C# 导出资源文件到硬盘
    C# 线程安全与 lock锁
    DAO设计模式(转)
  • 原文地址:https://www.cnblogs.com/shined/p/2588597.html
Copyright © 2020-2023  润新知