Oracle 10g enq:TX - contention等待事件(四)

2014-11-24 17:56:18 · 作者: · 浏览: 3
行级锁只有排他锁没有共享模式。


TM锁通常称为表级锁,可以通过手工发出lock命令获得,或者通过DML操作以及SELECT FOR UPDATE获得,表级锁可以防止其他进程对表加X排他锁,防止在对数据修改时,其他任务通过DDL来修改表结构或者truncate、drop表等操作。可以通过v$lock视图来观察锁定信息,其中TYPE字段表示锁定类型。对于TM锁LMODE字段又代表了不同级别的TM锁,这些级别包括2-row-S(SS)、3-row-X(SX)、4-share(S)、5-S/Row-X(SSX)和6-exclusive(X)。


当执行DML操作时,首先加TM锁,如果能获得锁定,则继续加TX事务锁。在一个会话中,一般只存在一个TX事务锁,在提交或回滚之前,该会话的所有DML操作都属于一个事务,使用一个回滚段,占用一个回滚段事务槽(Slot)。


以下通过SCOTT用户锁定一行记录,暂时不要提交:


scott@CCDB> update emp set sal = 4000 where empno = 7788;
1 row updated.


在另外session通过v$lock视图可以看到相关的锁定信息;


sys@CCDB> select sid,username from v$session where username = 'SCOTT';
SID USERNAME
---------- ------------------------------
1075 SCOTT
sys@CCDB> select * from v$lock where sid = 1075;
ADDR KADDR SID TY ID1 ID2 LMODE REQUEST CTIME BLOCK
---------------- ---------------- ---------- -- ---------- ---------- ---------- ---------- ---------- ----------
000000008F836260 000000008F8362B8 1075 AE 99 0 4 0 1208 0
00002BA14E74A7F8 00002BA14E74A858 1075 TM 69539 0 3 0 16 0
000000008DF49A30 000000008DF49AA8 1075 TX 65551 30498 6 0 16 0


此时表上的行级排他锁会阻塞对于表的DDL语句:


sys@CCDB> truncate table scott.emp;
truncate table scott.emp
*
ERROR at line 1:
ORA-00054: resource busy and acquire with NOWAIT specified or timeout expired


此外,TM锁定的ID1代表的就是锁定的对象号:


sys@CCDB> select owner,object_name from dba_objects where object_id = 69539;
OWNER OBJECT_NAME
--------------- ---------------
SCOTT EMP


而TX锁的ID1代表的是事务的回滚段回滚段号、事务槽号,ID2代表的是顺序号:


sys@CCDB> select trunc(65551/power(2,16)),mod(65551,power(2,16)) from dual;
TRUNC(65551/POWER(2,16)) MOD(65551,POWER(2,16))
------------------------ ----------------------
1 15


通过v$transaction视图也可以找到这个事务的信息(注意XIDSQN正是TX锁的ID2信息):


sys@CCDB> select XIDUSN,XIDSLOT,XIDSQN from v$transaction;
XIDUSN XIDSLOT XIDSQN
---------- ---------- ----------
1 15 30498


如果转储回滚段信息进行分析,再结合ITL事务槽,可以清晰地看到锁定的含义以及整个事务的处理过程。



2. 最常见的锁定:MR与AE锁
可能很多朋友都注意过,在v$lock视图中,最常见的其实是MR锁,也就是介质恢复锁(Media Recovery):


sys@CCDB> select * from v$lock where type = 'MR';
ADDR KADDR SID TY ID1 ID2 LMODE REQUEST CTIME BLOCK
---------------- ---------------- ---------- -- ---------- ---------- ---------- ---------- ---------- ----------
00000000BC2EE378 00000000BC2EE3D0 1097 MR 1 0 4 0 6984045 0
00000000BC2EE448 00000000BC2EE4A0 1097 MR 2 0 4 0 6984045 0
00000000BC2EE518 00000000BC2EE570 1097 MR 3 0 4 0 6984045 0
00000000BC2EE5E8 00000000BC2EE640 1097 MR 4 0 4 0 6984045 0
00000000BC2EE6B8 00000000BC2EE710 1097 MR 5 0 4 0 6984045 0
00000000BC2EE788 00000000BC2EE7E0 1097 MR 6 0 4 0 6984045 0
00000000BC2EE858 00000000BC2EE8B0 1