[English]
作者:
fuyuncat
来源:
www.HelloDBA.com
在TX等待中,还有一些其它不是很常见的情形会导致共享锁的等待,这类等待在10g就被记录为“enq: TX - contention”事件。例如,在以下情形中会出现“enq: TX - contention”等待事件:
1、一个事务要读取一条被另外一个事务加载了共享锁的记录,而这个事务恰好处在一个“不确定”的状态——prepared状态,这时读事务需要等待锁事务进入一个“确定”——被提交或回滚。在分布式事务中,可能由于各种原因(如网络中断、远程数据库突然宕机),会导致一些分布式事务处在prepared的状态。通过视图dba_2pc_pending可以找到这些事务:
SQL代码
- HELLODBA.COM>select local_tran_id, state from dba_2pc_pending;
- LOCAL_TRAN_ID STATE
- ---------------------- ----------------
- 3.4.9028 prepared
2、一些特殊操作要求等到系统中所有DML事务都结束(提交或回滚)才能进行,如修改表为ENABLE TABLE LOCK、修改表空间为READ ONLY。
SQL代码
- --s1
- HELLODBA.COM>alter table tc enable table lock;
- --s2
- HELLODBA.COM>select sid, event from v$session where event = 'enq: TX - contention';
- SID EVENT
- ---------- ----------------------------------------------------------------
- 301 enq: TX - contention
如果一直存在未结束的DML事务,alter table操作就失败:
SQL代码
- alter table tc enable table lock
- *
- ERROR at line 1:
- ORA-00054: resource busy and acquire with NOWAIT specified
注意:enq: TX - contention事件和其它TX队列事件不同,它的wait_class分类是Other,而非Apllication/Configuration。
3、在并发事务向同一表插入数据时,其中一个事务触发了数据段的自动扩展(AUTOEXTEND)操作分配了一个新的扩展段,这时需要先向该扩张段中写入一些段管理的元数据信息,此时,其他的插入事务就进入等待队列,记录enq: TX - contention事件。
解决方法
对于分布式事务造成的“enq: TX - contention”,可以参考metalink文档401302.1。
对于ALTER TABLE ENABLE TABLE LOCK和ALTER TABLESPACE READ ONLY这些操作,建议将数据库实例以RESTRICTED模式启动后在操作。
对于第三种情况,可以通过预先为对象设置较大的初始扩展段来减少自动扩展操作。