首页 > 代码库 > ORACLE的TM锁和TX锁

ORACLE的TM锁和TX锁

根据保护的数据不同,ORACLE的数据库锁分为以下几大类:

1.DML锁(data locks数据锁),用于保护数据的完整性;

2.DDL锁(dictionary locks字典锁),用于保护数据库对象的结构,例如表、索引的结构定义;

3.内部锁或闩(internal locks or latches),用于保护内部结构

在Oracle数据库中,DML锁主要包括TM锁和TX锁,其中TM锁称为表级锁,TX锁称为事务锁或行级锁。

  当Oracle执行DML语句时,系统自动在所要操作的表上申请TM类型的锁。当TM锁获得后,系统再自动申请TX类型的锁,并将实际锁定的数据行的锁标志位进行置位。这样在事务加锁前检查TX锁相容性时就不用再逐行检查锁标志,而只需检查TM锁模式的相容性即可,大大提高了系统的效率。TM锁包括了SS、SX、S、X 等多种模式,在数据库中用0-6来表示。不同的SQL操作产生不同类型的TM锁。

  在数据行上只有X锁(排他锁)。在 Oracle数据库中,当一个事务首次发起一个DML语句时就获得一个TX锁,该锁保持到事务被提交或回滚。当两个或多个会话在表的同一条记录上执行 DML语句时,第一个会话在该条记录上加锁,其他的会话处于等待状态。当第一个会话提交后,TX锁被释放,其他会话才可以加锁。

当Oracle数据库发生TX锁等待时,如果不及时处理常常会引起Oracle数据库挂起,或导致死锁的发生,产生ORA-60的错误。这些现象都会对实际应用产生极大的危害,如长时间未响应,大量事务失败等。

ORACLE里锁有以下几种模式: 

0:none 
1:null 空 
2:Row-S 行共享(RS):共享表锁,sub share  
3:Row-X 行独占(RX):用于行的修改,sub exclusive  
4:Share 共享锁(S):阻止其他DML操作,share 
5:S/Row-X 共享行独占(SRX):阻止其他事务操作,share/sub exclusive  
6:exclusive 独占(X):独立访问使用,exclusive

  我们可以从这个表找出至少2个东西,.第一是每种数据库操作都对应的是什么样的锁,第二是每种锁之间,如果遇到之后是否会产生冲突,所谓冲突就是是否会使当前的数据库操作夯住.如果两个操作锁定的是同一行,那么就会有冲突,后操作的会等待前一个操作完成之后再完成,否则会一直夯在那儿;如果不为同一行,那么则不会冲突,后操作的不会等待.举一个例子来说明:假设现在A操作为:对id=1的记录进行update,而B操作为:对id=2的记录进行删除,根据表格说明,在A上操作时在TM级别的锁会是RX,TX级别只有一个是X,在B上会有一个TM级别的锁会是RX,TX级别只有一个X,而根据表格说明,当RX遇到RX的时候,如果2个操作非同一条记录,那么则不会冲突,故AB两个操作均会按照各自的先加一个TM锁,再加一个TX锁,再顺利执行各自的操作,不会夯住。如果将B操作的记录id换位1,那么两个操作记录为同一条记录,在TM锁上会表现出冲突,所以B操作就会等待A操作完成提交后(也就是A的TX锁释放了后),B再相应的生成一个TX锁和一个TM锁再完成操作,否则的话会一直夯住,等待A释放TX锁.

create table CHGRANT_20170327 as select * from CHGRANT;
update CHGRANT_20170327 set UPDATETIME=‘‘ where operno=‘HANA0026‘ and options=‘1‘ and changeid=‘47‘;
select * from v$lock where type in (‘TX‘);

结果如下:

 技术分享

执行UPDATE语句但不提交:

update CHGRANT_20170327 set UPDATETIME=‘‘ where operno=‘HANA0026‘ and options=‘1‘ and changeid=‘47‘;

再看一遍TX锁的情况,结果为:

技术分享

明显多了一个SID为867的锁,查看SID为867的所有的锁:

select * from v$lock where sid in (‘867‘);

结果为:

技术分享

该结果与两个表的数据对应:

1.取TM锁的ID1,查询dba_objects表:

select * from dba_objects where object_id=‘3824866‘;

结果:

技术分享

2.取TX锁的ADDR,查询v$transaction表:

select * from v$transaction;

结果:

技术分享

另开窗口进行delete操作,事务会这被阻塞:

delete from CHGRANT_20170327 where operno=‘HANA0026‘ and options=‘1‘ and changeid=‘47‘;

再次查看TX锁:

select * from v$lock where type in (‘TX‘);

结果:

技术分享

又多出了一个SID为875的锁,查看SID为875的所有锁:

select * from v$lock where sid in (‘875‘);

结果:

技术分享

再返回查看这两个新锁(SID为867和875)的v$lock情况:

select * from v$lock where sid in (‘867‘,‘875‘);

结果:

技术分享

注意SID为867(即update那个操作)的BLOCK变为了‘1‘。

 

现在ROLLBACK那个update操作(867),查看v$lock:

select * from v$lock where sid in (‘867‘,‘875‘);

结果:

技术分享

可见867的锁记录已经被释放掉了。

此时另一窗口的delete操作终于返回了,现在也rollback它。

select * from v$lock where sid in (‘867‘,‘875‘);

结果:

技术分享

两个事务的锁都被释放了。

 

最后补充一个操作,创建索引的时候会生成的锁操作:

创建索引的同时,查询v$lock表

可以发现在创建索引的会生成2个TM锁,锁类别分别为4和3,我们查询这2个TM分别锁定的是什么对象:

根据查询结果发现lmode=4的object_id为55160的对象对应的是TTT这个表,LMODE=4对应的是TM的S锁

 

原文章地址:

http://blog.csdn.net/vertual/article/details/34540555

http://blog.sina.com.cn/s/blog_95b5eb8c0101i22x.html

ORACLE的TM锁和TX锁