本文对一些基本概念只是一带而过甚至略过,更多的请参考官方文档。
What is Lock?
Oracle的锁机制用于管理对共享资源的并发访问。锁由Oracle自动管理,当事务(Transaction)结束后,自动释放。
锁可分为两个基本类型:Share(共享锁),Exclusive(排它锁)
What is Deadlock?
当两个或多个用户等待彼此之间的资源时发生死锁(Deadlock),避免死锁的办法就是使事务按照一定的顺序对表加锁,同时考虑先加最昂贵(排它性最强)的锁。
Concurrency of Transactions
1、sql server中读数据会用到页级锁(sql server中页相当于oracle的块),如执行select * from t查询会先锁定第一页,读完之后立即释放对第一页的锁,然后锁定第二页。Oracle对读操作是不加锁的(除了select … for update语句,这条语句会对表加RS锁,对行加TX锁,当你修改了表中的某一行后,表上的RS锁会转换为RX锁,这种变化称为Lock Conversion),因此读操作不会阻塞读和写操作。
2、Oracle采用行级锁。值得注意的是,其他数据库会进行锁升级(Lock Escalation),所谓锁升级是指调整锁的粒度,将多个低粒度的锁替换成少数的更高粒度的锁,以此来降低系统负荷。比如当锁定表中大多数行时,行级锁会升级为表级锁。 而Oracle的行级锁只是在数据块内的行上置一个锁标志位指向ITL slot,并没有专门用链表来管理行级锁,大大降低了系统的管理成本,因而Oracle不进行锁升级。而sql server早期只提供页级锁,对于非聚簇表,由于所有数据都会插入到表的最后一页,所以大多数情况下不允许两个用户同时修改表。后来sql server也引了行级锁,行级锁降低了写操作之间的冲突。
3、sql server中如果你要查询一个表,而所需的页被一个更新锁锁住,那么你就必须等待…Oracle采用多版本并发控制,通过Undo block避免“脏”读,因此写操作不会阻塞读操作,这些都极大提高了Oracle的并发处理能力。
Types of Locks
根据保护对象的不同,锁可以分为以下几大类
DML(数据锁): 保护数据的完整性
DDL(数据字典锁):保护数据库对象的结构
Internal locks and latches:保护内部数据库结构
其中DML按其封锁粒度又可分为表级锁(table lock)和行级锁(row lock)
行级锁也叫事务锁,简称TX锁。行上面只有X锁(排它锁),没有S锁(共享锁)。
表级锁简称 TM锁,可分为以下5种
S: share
X: exclusive
RS: row share
RX: row exclusive
SRX: share + row exclusive
备注:RS,RX是DML操作产生的常见表级锁,他们都只是意向锁,真正的加锁粒度还是在行级。These DML operations require table locks for two purposes: to reserve DML access to the table on behalf of a transaction and to prevent DDL operations that would conflict with the transaction.
表级锁的获取方式及之间的关系如下:
SQL语句 | 表锁模式 | 允许的锁模式 |
Select * from table_name…… | 无 | RS、RX、S、SRX、X |
Insert into table_name…… | RX | RS、RX |
Update table_name…… | RX | RS、RX |
Delete from table_name…… | RX | RS、RX |
Select * from table_name for update | RS | RS、RX、S、SRX |
lock table table_name in row share mode | RS | RS、RX、S、SRX |
lock table table_name in row exclusive mode | RX | RS、RX |
lock table table_name in share mode | S | RS、S |
lock table table_name in share row exclusive mode | SRX | RS |
lock table table_name in exclusive mode | X | 无 |
Views of Locks
v$lock, v$locked_object
显示当前所有TM、TX锁的信息
select sid,type,id1,id2,
decode(lmode,0,'None',1,'Null',2,'Row share',
3,'Row Exclusive',4,'Share',5,'Share Row Exclusive',6,'Exclusive')
lock_type,request,ctime,block
from v$lock
where TYPE IN('TX','TM');
显示哪些对象被哪些会话锁住:
select rpad(oracle_username,10) o_name,session_id sid,
decode(locked_mode,0,'None',1,'Null',2,'Row share',
3,'Row Exclusive',4,'Share',5,'Share Row Exclusive',6,'Exclusive') lock_type, object_name ,xidusn,xidslot,xidsqn
from v$locked_object,all_objects
where v$locked_object.object_id=all_objects.object_id;
这两个表都含有sid字段,连接v$session,v$sqltext可以很快找到对应sql语句。




最新回复