Oracle多粒度封锁机制研究
在Oracle数据库并发环境下,对于表,既要保护其数据,又要保护其结构(结构信息存储在数据字典中),很自然,针对这两种保护要求,就有了两种类型(Type)的锁:保护数据的锁我们叫数据锁(DML locks或data locks),保护结构的我们叫字典锁(DDL locks或dictionary locks)。
对于数据锁,为了适应不同事务的不同要求,提供两个层次(粒度)的锁,即表级锁(Table Locks ,TM)与行级锁(Row Locks ,TX)。
在这两个层次上,经典的上锁的方式(Mode)有两种,即共享锁(S锁)与排它锁(X锁)。
为了方便地进行锁冲突的检测,希望在表(上)级能够标识行(下)级加锁的情况,这就引入了“意向锁”(intention lock mode)的概念。根据在行级要加S锁或X锁的不同,在表级相应的就有两种意向锁,即:如果事务要在行级获得S锁,它需要首先在表级获得意向共享锁(Intent Share Lock,IS锁);如果事务要在行级获得X锁,它需要首先在表级获得意向排它锁(Intent Exclusive Lock,IX锁)。这两种意向锁与经典的S锁、X锁组合,还会产生一种新的锁:共享意向排它锁(Share Intent Exclusive Lock,SIX锁),它表示持有该锁的事务在表级加了传统的共享锁(S锁),同时该事务还将对表中的某些行加排它锁(X锁)。
这样,在表级数据锁的加锁方式就有了5种:即S、X、IS、IX、SIX。
在Oracle中,与IS对应的锁叫做Row Share Table Locks (RS)或subshare table lock, SS,它可以通过SELECT ... FOR UPDATE语句获得,但需要注意的是,这个语句在行级获得的也是排它锁,即如果两个SELECT ... FOR UPDATE语句要选定同一行,则后面的事务将被阻塞,这是与上面一般意义的定义有所不同,这时RS锁可以理解为持有该锁的事务将要修改选定的某些行。
在Oracle中,与IX对应的锁叫做Row Exclusive Table Locks (RX)或subexclusive table lock, SX,它可以通过INSERT/UPDATE/DELETE语句获得,它表征持有该锁的事务已经修改了表中的某些行。
在Oracle中,与SIX对应的锁叫做Share Row Exclusive Table Locks (SRX)或sshare-subexclusive table lock, SSX。
这样,Oracle对表级数据锁的加锁方式就有:即S、X、RS、RX、SRX等5种;而在行级只有X锁。
在Oracle中,对于字典锁,也有共享与排它之分:Share DDL Locks与Exclusive DDL Locks。对于要获得Exclusive DDL Locks的DDL操作(如ALTER、DROP等),它还必须要获得该表排它的数据锁,这样如果在某个表上有未提交的事务(即该表有某种类型的表级锁),其它SESSION提出的DROP表的操作就不会成功,因为它要向表施加X锁,与表上已有的锁不相容。
所以说,表级的数据锁既能防止与之冲突的DML操作,也能防止与之冲突的DDL操作,但不能因此就把表级的数据锁与字典锁混为一谈。