日期:2014-05-16  浏览次数:20456 次

理解锁和闩(3)TX锁和TM锁

 

 

          oracle没有锁管理器和锁列表,这样可以避免行级锁维护的开销和行级锁数量不足导致的争用问题。在Oracle的每行数据上,都有一个标志位来表示该行数据是否被锁定,要查看某一行是否被锁定,必须直接找到这一行,而不要指望能从哪个列表得到答案,事务只是找到数据。其locking过程如下:
              ㈠ 找到想锁定的那一行的地址
              ㈡ 到达那一行
              ㈢ 锁定这一行
          在这行的位置,而非某个锁列表。如果这一行已经锁定,则等待锁定它的事务结束,除非使用nowait选项。

 

            保护元数据---->TM锁(表级锁)
            保护数据  ---->TX锁(事务锁)
            v$lock列:ID1、ID2
            对TM锁,ID1表示被locking对象的object_id,ID2始终为0
            对TX锁,ID1表示该事务的xidusn、xidslot,ID2表示xidsqn
            对ID1的拆解:

          

14:14:56 hr@ORCL (^ω^) select id1,id2,type from v$lock where type='TX';

       ID1        ID2 TYPE
---------- ---------- ----
    524320       1748 TX
14:16:56 hr@ORCL (^ω^) select 524320/65536 xidusn,mod(524320,65536) xidslot from dual;

    XIDUSN    XIDSLOT
---------- ----------
8.00048828         32


            事务锁不是行级锁。行级锁触发事务锁。一个事务只有一个事务锁,但可以有多个行级锁。TX锁用作一种排队机制:请求锁的事务会排队,等待目前持有锁的事务执行,然后得到数据。
            事务中DML或select ...for update都会得到一个TX锁。

     session 1:scott
     SQL> update dept set dname=initcap(dname);
    
     已更新4行。
     SQL> select username,l.sid,trunc(id1/power(2,16)) xidusn,bitand(id1,to_number('ffff','xxxx'))+0 slot,
       2         id2 sqn,lmode,request
       3    from v$lock l,v$session s
       4   where l.type='TX' and
       5         l.sid=s.sid and
       6         s.username=USER
       7  /
    
     USERNAME          SID     XIDUSN       SLOT        SQN      LMODE    REQUEST
     ---------- ---------- ---------- ---------- ---------- ---------- ----------
     SCOTT             154         10         40       1395          6          0
     SQL> select xidusn,xidslot,xidsqn from v$transaction;