Oracle的锁类型和相关试图
上次谈了谈Oracle锁的机制,并介绍了一些案例(http://www.cnblogs.com/yzyi/p/7158732.html)。今天来说一说在Oracle的环境下,锁的类型、作用方式以及官方提供的相关试图。
锁类型
用户想要修改数据或者数据结构,必须要先获得对象的锁,以防止被其他会话修改,如果已经有其他会话获得了对象上的锁,那么将会一直等待,直到其他会话释放锁。
Oracle中主要来说有三种类型的锁:
1.DML锁:一般来说是针对SELECT、INSERT、UPDATE、MERGE和DELETE语句建立的锁,目的是为了保护数据的一致性;
2.DDL锁:针对DDL语句如ALERT、CREATE等语句建立的锁,目的是为了保护对象结构定义的一致性;
3.内部锁和闩:Oracle采用内部所和闩保护数据库的内部数据结构。
DML锁
DML锁可能是针对某一特定行数据的行级锁,也可能是针对表中所有行的表级锁。当用户拥有DML锁,其他用户不能修改持有锁的数据,也不能修改数据表的结构定义。DML锁主要分为两类:TX锁(事务锁或行级锁)和TM锁(表级锁)。
TX锁
TX锁又称为事务锁或行级锁,当用户对某一条数据进行修改时,就会对这条数据加上一个TX锁。需要注意的是,Oracle数据库对于锁的管理,有它独到的高明之处。不同于其他数据库,Oracle没有传统的锁管理器,用于处理锁的串行事务管理;Oracle对数据行加锁时,将事务ID存储在包含数据的块上,即使释放锁,这个事务ID仍然会保留下来,这个事务ID是事务所独有的,表示了回滚段号、槽和序列号。当有其他用户想申请该行数据的锁时,会检查数据块上是否存在活动的事务ID,如果存在,那么将会等待这个事务的提交或者回滚。
TM锁
TM锁又称为表级锁,用于确保在修改表数据的时候,表的结构不会被改变。TM锁的总数量是可以手动设定的,甚至可以设置为0。当TM锁设置为0,说明禁止了一切的DDL操作。
当执行DML操作时,首先会申请数据所在表的TM锁,当获得TM锁后,再申请TX锁,并将锁定位到修改的数据行上。如果某个用户想要修改数据,首先检查TM锁的可用性,这样就避免了锁的逐一检查,大大的提高了效率。
DDL锁
DDL锁用于保护在执行DDL操作时,对象不会被其他会话修改。在DDL语句执行期间,对象会一直持有DDL锁,执行完成后立即释放。需要注意的是,为了防止阻塞,Oracle中DDL语句一定会(隐式)提交,即使提交失败也是如此,在此之前执行的所有操作都会随之提交。如果不想DDL语句隐式提交,可以采用自治事务(autonomous transaction)。
DDL锁有三类:排他DDL锁、共享DDL锁、可中断解析锁。
排他DDL锁
排他DDL锁(Exclusive DDL lock)会阻止其他会话得到DDL锁或TM锁。也就是说,当对象加上排他DDL锁时,其他会话只能执行查询操作。
共享DDL锁
共享DDL锁(Share DDL lock)会保护对象的结构,其他对象不能修改,但是可以修改表的数据。
多数的DDL操作都会加上一个排他DDL锁,如ALTER、DROP等;在创建存储的编译对象(如过程和视图)时,会对依赖的对象加这种共享DDL锁。
需要注意的是,有些DDL操作没有DDL锁也可以进行,如以ONLINE模式创建索引,这时会申请一个低级的TM锁,以此保护对象的结构不被其他会话修改。在此期间,仍可以进行DML操作,Oracle会对修改的数据自动维护一个记录,最终将修改后的数据应用至新建的索引,这样就能大大的提高数据的可用性。
可中断解析锁
你的会话解析一条语句时,对于该语句引用的每一个对象都会加一个解析锁。加这些锁的目的是:如果以某种方式删除或修改了一个被引用的对象,可以将共享池中已解析的缓存语句置为无效(刷新输出)。
锁视图
1.V$LOCK
|
Column |
Datatype |
Description |
|
ADDR |
RAW(4 | 8) |
Address of lock state object |
|
KADDR |
RAW(4 | 8) |
Address of lock |
|
SID |
NUMBER |
Identifier for session holding or acquiring the lock |
|
TYPE |
VARCHAR2(2) |
Type of user or system lock The locks on the user types are obtained by user applications. Any process that is blocking others is likely to be holding one of these locks. The user type locks are: TM - DML enqueue TX - Transaction enqueue UL - User supplied --我们主要关注TX和TM两种类型的锁 --UL锁用户自己定义的,一般很少会定义,基本不用关注 --其它均为系统锁,会很快自动释放,不用关注 |
|
ID1 |
NUMBER |
Lock identifier #1 (depends on type) |
|
ID2 |
NUMBER |
Lock identifier #2 (depends on type) ---当lock type 为TM时,id1为DML-locked object的object_id ---当lock type 为TX时,id1为usn+slot,而id2为seq。 --当lock type为其它时,不用关注 |
|
LMODE |
NUMBER |
Lock mode in which the session holds the lock: 0 - none 1 - null (NULL) 2 - row-S (SS) 3 - row-X (SX) 4 - share (S) 5 - S/Row-X (SSX) 6 - exclusive (X) --大于0时表示当前会话以某种模式占有该锁,等于0时表示当前会话正在等待该锁资 源,即表示该会话被阻塞。 --往往在发生TX锁时,伴随着TM锁,比如一个sid=9会话拥有一个TM锁,一般会拥有一个 或几个TX锁,但他们的id1和id2是不同的,请注意 |
|
REQUEST |
NUMBER |
Lock mode in which the process requests the lock: 0 - none 1 - null (NULL) 2 - row-S (SS) 3 - row-X (SX) 4 - share (S) 5 - S/Row-X (SSX) 6 - exclusive (X) |