根据保护的数据不同,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