数据记录被锁
我们知道,Oracle中事务产生的索都是行级锁。也就说,事务在对表做更新操作(Update、Delete)时,只在针对数据块中需要更新的数据记录加锁。这种类型的锁就是我们最常见的锁。看下面的例子:
会话1:
会话2:
会话1锁住了a=1的记录,会话试图删除该记录时,被hung住。
并且,如果将t_lock的数据块dump出来的话,也可以看到在记录行上的锁标志
其中,0x1对应的是产生锁的事务在数据块itl列表中的条目号。
数据块中itl条目达到最大限制时产生的锁
ITL(Interested Transaction List)直白点说就是对该数据块“有兴趣”的事务列。也就是会对该数据块进行修改的事务。一个表的数据块上同时最多可以有多少个事务对其进行更新,是由创建表时的参数maxtrans指定的。但是,如果表建立在基于9i新特性ASSM(自动段空间管理)的表空间上的话,那么指定的maxtrans就无效,一律都是255。比如上面的例子中,我们指定了maxtrans为3(表空间不是ASSM),所以同时最多只能有3个事务对一个数据块进行更新。看下面的例子。
先给上面的表多插入一些数据:
会话1:
会话2:
会话3:
会话4:
前面已经占用了3个itl slot,第4个事务再申请itl时被hung住了。
Dump出数据块,可以看到itl已经达到最大限制条目数:
这里我们需要提出另外一个问题,如果事务操作不是update、delete,而是进行Insert操作,会不会也会达到maxtrans的限制呢?做个试验看下吧:
会话1:
会话2:
会话3:
会话4:
这时,尽管已经分配itl条目给三个事务,但是第四个事务在做insert插入操作时并没有被hung住。
看下数据块dump内容:
我们发现,确实只有三个transaction在这个数据块上。那么还有一个事务呢?别急,把下一个数据块dump出来看看:
原来如此!在做insert操作时,如果发现数据块已经达到maxtrans的最大限制,就从freelist中取出下一空闲数据块进行插入操作,而不管是否达到pctused的限制了。
Table上有Index时达到maxtrans限制
以上的测试是针对table上没有index时做的测试。当在table上建了index,情况就变得复杂多了。
· 场景一:
会话1:
会话2:
(注意:以上操作都会索引列)
会话3:
(注意:这个会话没有涉及索引列)
会话4:
第4个会话被hung住了:
我们的table上的maxtrans是5,这里并没有达到,而index上的maxtrans是3,第4个Transaction被hung。这里似乎可以下一个结论:table上有index的话,如果达到index上的maxtrans限制,后面的事务就会被hung住。但是,请注意第3个会话,他的操作并没有涉及到索引列,那么去掉第3个会话会怎样?
· 场景二:
会话1:
会话2:
(注意:以上操作都会索引列)
会话3:
第3个会话被hung住了:
这里,第3个会话就被hung住了。那就是说对有index得情况来说,itl数的限制是minx(maxtrans_of_index1 - 1, maxtrans_of_index2 – 1..., maxtrans_of_table) 。
我们前面提到,如果在insert时发现数据块的itl数已经达到maxtrans的限制,那么会在一个新的数据块进行插入,以避免会话阻塞。那么有了index以后,是否还是这样呢?看下面这种情况。
· 场景三:
会话1:
会话2:
(注意:以上操作都会索引列)
会话3:
第3个会话被hung住了:
来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/35489/viewspace-997020/,如需转载,请注明出处,否则将追究法律责任。
转载于:http://blog.itpub.net/35489/viewspace-997020/
本文详细探讨了Oracle数据库中事务产生的TX锁机制,包括数据记录锁、ITL条目限制及索引对ITL的影响等内容。
1493

被折叠的 条评论
为什么被折叠?



