TX锁是保护事务的,事务结束时便会释放。因此,为获得TX锁为等待的会话,要等到拥有锁的会话的事务结束为止。
- SQL> select name,parameter1,parameter2,parameter3 from v$event_name where name like '%enq: TX%';
-
- NAME PARAMETER1 PARAMETER2 PARAMETER3
- ------------------------------ --------------- --------------- ---------------
- enq: TX - row lock contention name|mode usn<<16 | slot sequence
- enq: TX - allocate ITL entry name|mode usn<<16 | slot sequence
- enq: TX - index contention name|mode usn<<16 | slot sequence
- enq: TX - contention name|mode usn<<16 | slot sequence
(1)欲修改特定行时,相关的等待事件是enq: TX - row lock contention。
修改相同行,是发生TX锁引起争用的最普遍的情况。TX锁保护的资源是“事务”。修改相同行伴随着的TX锁争用,完全是应用程序的问题。长时间执行的update或delete命令最好是在事务较少的时段执行。还有,优化update或delete命令本身也是改善性能的另一种方法。特别是对大量数据执行update,不仅引起TX锁争用,而且会引起许多性能问题。
代替大量执行的update的一种方法如下:
(1)创建一个复制既存表old_table的新表new_table,然后将修改内容存储。即利用“create table new_table as select * from old_table”之类的命令。
(2)在新创建的表new_table中,创建与old_table相同的索引等。
(3)对于既存表old_table执行drop,然后将新表new_table重命名为old_table。
执行以前工作时,若是同时使用nologging和Parallel选项,就可以将所愿的工作更快,而且可以在利用更少资源的前提下实行。
(2)欲修改特定行上唯一键(unique key)或主键(primary key)相应的列时,相关的等待事件是enq: TX - row lock contention。
发生唯一键或主键冲突时也会发生TX锁争用。唯一键冲突引起的TX锁争用完完全全是应用程序的问题。最好的解决方法就是使用sequence创建唯一键。
(3)欲修改的块的ITL上想要登记自身相应的事务条目时,相关的等待事件是enq: TX - allocate ITL entry。
所有事务在修改块之前,必须在块头的ITL上等级条目。
(4)欲修改已创建位图索引(bitmap index)的列值时,相关的等待事件是enq: TX - row lock contention。
位图索引是为了对那些读取频繁而写入工作较少的表,即将select语句性能最大限度的优化而考虑的。对于DML频繁的表,随意使用位图索引相当危险。每当行被修改时,都要计算位图值,因此DML本身的性能将下降。而且多个会话同时执行DML时,更是发生过多的TX锁争用。若对DML频繁的表想要保障sql语句的性能,与其使用位图索引,不如使用Materialized View之类的功能。