我们都知道在Oracle中实现了细粒度的行锁row lock,且在ORACLE的内部实现中没有使用基于内存的行锁管理器,row lock是依赖于数据块本身实现的。换句话说判定一行数据究竟有没有没锁住,要求Server Process去pin住相应的block buffer并检查才能够发现。 但是试想一个场景,若process A 通过update语句锁定了数据表 Z数据块上的一行数据, 并长时间既没有rollback亦没有commit;此时Process B也运行了一条DML语句, 它通过索引找到rowid并找到了 Z数据块, 它发现这一行数据已经被process A发起的一个事务的ITL锁住了,它可能试图做一些cleanout操作,但是发现被锁住的row在相关的事务表中仍未被commit, 那么很抱歉的是Process B需要进入"enq: TX - row lock contention"的等待事件了。 问题在于Process B的无尽等待的终结在哪里呢? 有同学肯定会说只要Process A释放了其锁定的row,那么Process B就会立即结束其"enq: TX - row lock contention"等待了。 事实是这样的吗?
本文转自maclean_007 51CTO博客,原文链接:http://blog.51cto.com/maclean/1278318