TX ENQUEUE阻塞的理解

TX ENQUEUE阻塞的理解
Kevin Zou
2011-9-19
当一个SESSION开启新事务时,该SESSION 就要获取一个TX ENQUEUE。该TX ENQUEUE在会话的第一个DML就开始获得,一直到事务提交或者回滚。这里LOCK 和ENQUEUE的同义词。
通过回滚段号,事务槽号每个事务都是唯一的。具体的点就是通过V$SQL的ID1和ID2来得到。TX ENQUEUE主要是用来建立一个队列机制,所以其他的事务等待事务的完成。
一个事务在等待TX ENQUEUE锁是因为以下原因:
1) 其他的事务锁定了特定的行;
2) 当两个事务想插入相同的唯一健值到表中,两个事务都没有提交;后来会话就要等待;
3) 没有足够的ITL。
其他的事务锁定了特定的行例子:
SESSION-1:
SQL> create table t(id int);

表已创建。
SQL> alter table t add constraint t_pri primary key (id) ;

表已更改。


SQL> insert into t values(1);

已创建 1 行。

SQL> COMMIT;

SQL> update t set id = 2 where id =1;

已更新 1 行。

新创建一个会话 SESSION-2:
SQL> conn /as sysdba
已连接。
SQL> update t set id =4 where id = 1;

这时SESSION-2被阻塞;

通过SESSION-1查看:

SQL> SELECT sid,id1,id2,type,lmode,request,block FROM v$lock where sid in (139,1
40) and type='TX' order by sid;

       SID        ID1        ID2 TY      LMODE    REQUEST      BLOCK
---------- ---------- ---------- -- ---------- ---------- ----------
       139     983082          6 TX          6          0          1
       140     983082          6 TX          0          6          0
SQL>  select P1, p1raw, p2,p3 from v$session where sid = 140;

        P1 P1RAW            P2         P3
---------- -------- ---------- ----------
1415053318 54580006     983082          6

SQL> select chr(bitand(&&P1,-16777216)/16777215)||chr(bitand(&&P1,16711680)/6553
5) "Lock", mod(&&p1,16) "MODE"
  2  from dual;
原值    1: select chr(bitand(&&P1,-16777216)/16777215)||chr(bitand(&&P1,16711680
)/65535) "Lock", mod(&&p1,16) "MODE"
新值    1: select chr(bitand(1415053318,-16777216)/16777215)||chr(bitand(1415053
318,16711680)/65535) "Lock", mod(1415053318,16) "MODE"

Lo       MODE
-- ----------
TX          6
SQL> select ROW_WAIT_OBJ#,
  2                    ROW_WAIT_FILE#,ROW_WAIT_BLOCK#,ROW_WAIT_ROW#
  3                      from v$session
  4                     where sid=140;

ROW_WAIT_OBJ# ROW_WAIT_FILE# ROW_WAIT_BLOCK# ROW_WAIT_ROW#
------------- -------------- --------------- -------------
        52326              1           60618             0

SQL> select object_name, object_id from dba_objects where object_id = 52326;

OBJECT_NAME                                      OBJECT_ID
T                                             52326

SESSION-1 的ID 为139
SESSION-2 的ID 为140
因为140 会话想更新和139相同的数据,但是139没有提交,140只有等待;139 阻塞了140.

插入相同的唯一健值的例子:
在SESSION-1#:
SQL> insert into t values(10);

已创建 1 行。
在SESSION-2#:
SQL> insert into t values(10);
这时窗口被HOLD住了。
回到第一个SESSION-1#:
SQL>  SELECT sid,id1,id2,type,lmode,request,block FROM v$lock where sid in (139,140) and type='TX' order by sid;

       SID        ID1        ID2 TY      LMODE    REQUEST      BLOCK
---------- ---------- ---------- -- ---------- ---------- ----------
       139    1114159          6 TX          6          0          1
       140     852007          6 TX          6          0          0
       140    1114159          6 TX          0          4          0

session-2#除了拥有自身的TX ENQUEUE外,还以共享模式申请了SESSION-1#拥有的TX ENQUEUE。
SESSION-1#
SQL> commit;

提交完成。
SESSION-2#
SQL> insert into t values(10);
insert into t values(10)
*
第 1 行出现错误:
ORA-00001: 违反唯一约束条件 (SYS.T_PRI)

没有足够的ITL例子:
ORACLE在每个BLOCK 头开辟了一块区域来记录哪行数据被哪个事务锁住,这块区域就是ITL,全称为interested transaction list。
对象的INITRANS 和 MAXTRANS 属性确定了对象块的ITL大小。INITRANS是至少数值,而MAXTRANS指定了上限。每个想修改数据块中的数据必须获得数据块的ITL的槽位。如果申请槽位的数量大于MAXTRANS,那后来的SESSION必须等待,知道某个槽位被释放出来。
SESSION-1#:
SQL> ALTER TABLE t MAXTRANS 1;
表已更改。
SQL> select * from t;

        ID
----------
        10
        20

SQL> update t set id =1 where id =10;

已更新 1 行。
在SESSION-2#中,
SQL> update t set id =2 where id =20;

已更新 1 行。
在10GR2的环境中模拟不了这个例子。是因为MAXTRANS 不起作用了。
SQL> select table_name,INI_TRANS,MAX_TRANS from user_tables where table_name='T'
;

TABLE_NAME                      INI_TRANS  MAX_TRANS
------------------------------ ---------- ----------
T                                       1        255

看到这个TABLE 的MAXTRANS还是255,无法更新。

-THE END-

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/40239/viewspace-707937/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/40239/viewspace-707937/

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值