Oracle数据库支持多个用户同时与数据库进行交互,每个用户都可以同时运行自己的事务,从而也需要对并发访问进行控制。Oracle也是用“锁”的机制来防止各个事务之间的相互影响,对并发访问进行控制的,保证数据的一致性和完整性。当一个事务或操作企图防止另一个事务对其操作的对象产生影响时,该事务或操作就对该对象进行锁定,其他事务就只能在该事务释放锁之后才能操作该对象。

在大多数情况下,锁对于开发人员来说是透明的,不用显式地加锁,即不用指定锁的分类、级别、类型或模式。如,当更改记录时,Oracle会自动地对相关的记录加相应的锁;当执行一个PL/SQL过程时,该过程就会自动地处于被锁定的状态,允许其他用户执行它,但不允许其他用户采用任何方式更改该过程。当然,Oracle也允许用户使用Lock Table语句显式地对被锁定的对象加指定模式的锁。

锁有2种最基本、最简单的类型:排他锁(eXclusive lock,即X锁)、共享锁(Share lock,即S锁)。这两种锁及其锁定的示意图如下图所示。该图中显式了不同的锁的作用,以及相互之间的相容规则。

排他锁又称为写锁。如果事务T在数据库对象A上加了X锁,则只允许T读取、更改A。其他任何事务Ti都既不能对A加S锁也不能加X锁,直到T释放A上的X锁为止。这就保证了其他事务Ti在事务T释放A上的X锁之前,不能再读取、更改、使用A,即保护A不被同时地读、写。

共享锁又称为读锁。如果事务T在数据库对象A上加了S锁,则只允许T读取A但不能更改A。其他任何事务Ti都只能对A加S锁而不能加X锁,直到T释放A上的S锁为止。这就保证了其他事务Ti在事务T释放A上的S锁之前,只能读取A但不能更改A,即保护A不被同时地写。

锁除了对操作进行限制外,锁对锁也进行限制,排他锁与共享锁的相容规则如表所示。

一、锁定的粒度与意向锁

锁定对象的大小被称为锁定的粒度(granularity)。锁定对象可以是逻辑单元(如数据库、表、记录、列、索引等),也可以是物理单元(如数据页、索引页等)。

锁定的粒度与系统的并发度和并发控制的开销密切相关。一般地,锁定的粒度越大,需要锁定的对象就越少,可选择性就越小,并发度就越小,开销就越小;反之,锁定的粒度越小,需要锁定的对象就越多,可选择性就越大,并发度就越大,开销就越大。

例如,如果锁定的粒度是表,事务T1需要操作表A中的记录r1,则T1必须对包含记录r1的表A加锁。在T1对A加锁之后,事务T2需要操作表A中的记录r2,因此就需要对表A加锁,但此时因为T1已经在表A上加了锁,所以T2的加锁就会失败,就被迫等待,直到T1释放锁为止,事务T1和T2就不能并发执行了;如果锁定的粒度是记录,则事务T1可以对表A中的记录r1加锁,同时事务T2也可以对表A中的记录r2加锁,所以事务T1和T2就可以并发执行了,并发度就增大了,但维护这个并发度就需要更多的开销了。

1、多粒度锁定与多粒度树

如果在一个数据库管理系统中,同时支持多种锁定粒度供事务选择,这种锁定方法就被称为多粒度锁定(multiple granularity locking)。

如下图所示是一个四级的多粒度树。该树的根节点是数据库,表示最大的粒度;页节点是列,表示最小的粒度。

从前面的例子可知,选择锁定粒度时应该同时考虑并发度与开销两个因素。以求最优的效果。一般地,需要处理大量记录的事务可以以表为锁定粒度;需要处理多个表中的大量记录的事务可以以数据库为锁定粒度;而只需要处理某个表中少量记录的事务,则可以以记录为锁定粒度。

多粒度锁定协议是指,允许对多粒度树中的节点单独地加锁,另外,对一个节点加锁还意味着对这个节点的各级子节点也加同样的锁。

因此,可以用两种方法对多粒度树中的节点加锁:显式锁定、隐式锁定。显式锁定是在事务中明确指定要加在节点上的锁;隐式锁定是由于在其上级节点中加显式锁时而使该节点获得的锁。

在多粒度锁定中,显式锁定与隐式锁定的作用与相容规则都是一样的。因此,当系统检查锁定的冲突时,不仅要检查显式锁定还要检查隐式锁定。

一般地,当对一个节点加锁时,系统第一要检查在该节点上有无显式锁定与之冲突;第二要检查其所有上级节点有无显式锁定与之冲突,以便查看在该节点上加该显式锁定,是否会与从上级节点获得的隐式锁定有冲突;第三要检查所有下级节点有无显式锁定与之冲突,以便查看在该节点上加该显式锁定,是否会使下级节点从该节点获得的隐式锁定与其显式锁定有冲突。

这种检查锁定冲突的方法的效率很低,所以引进了意向锁(Intended lock)的概念。

2、意向锁

意向锁的含义是,如果对一个节点加某种意向锁,则会对该节点的各级下级节点加这种锁;如果对一个节点加某种锁,则必须先对该节点的各级上级节点加这种意向锁。

例如,对记录r1加锁时,必须先对它所在的表A加意向锁。于是,事务T1对表A加X锁时,系统只需要检查根节点数据库D和表A是否已经加了不相容的锁,而不再需要检查表A中每个记录是否加了X锁。

有如下几种意向锁。

一、IS锁(Intended Share lock,意向共享锁)

如果对一个节点加IS锁,则表示对它的所有下级节点有加S锁的意向;如果对一个节点加S锁,则必须先对该节点的各级上级节点加IS锁。

二、IX锁(Intended eXclusive lock,意向排他锁)

如果对一个节点加IX锁,则表示对它的所有下级节点有加X锁的意向;如果对一个节点加X锁,则必须先对该节点的各级上级节点加IX锁。

三、SIX锁(Share Intended eXclusive lock,共享意向排他锁)

如果对一个节点加SIX锁,则表示对它加S锁,然后再加IX锁,即SIX=S+IX。例如,如果事务T对表A加SIX锁,则表示事务T要读取整个表(S锁的作用),同时还会更新某些记录(IX锁的作用)。

包括意向锁的各种锁之间的相容规则如表所示。

例如,当事务T对表A保持的锁是S锁时,事务Ti不可以获得对表A的IX锁,但可以获得对A的IS锁。所以S锁与IX锁的强度相当,但比IS锁的强度要强。

同上理,可以逐个地推导出这些锁的强度关系,如图所示。图中上面的锁比下面的锁的强度要强,同级的锁强度相当。一个事务在申请锁定时以强锁代替弱锁是安全的(但会降低并发度),反之则不然。申请锁定时应该按自上而下的次序进行,释放锁定时则应该按自下而上的次序进行。

具有意向锁的多粒度锁定方法能提高系统的并发度,减少加锁和解锁的开销,已经在实际DBMS中得到应用,如Oracle数据库。

二、锁的分类

Oracle主要有2种锁:DDL锁(字典锁)、DML锁(数据锁)。

1 DDL

当用户发布DDL(Data Definition Language)语句时会对涉及的对象加DDL锁。由于DDL语句会更改数据字典,所以该锁也被称为字典锁。

DDL锁能防止在用DML语句操作数据库表时,对表进行删除,或对表的结构进行更改。

对于DDL锁,要注意的是:

$$ DDL锁只锁定DDL操作所涉及的对象,而不会锁定数据字典中的所有对象。

$$ DDL锁由Oracle自动加锁和释放。不能显式地给对象加DDL锁,即没有加DDL锁的语句。

$$ 在过程中引用的对象,在过程编译结束之前不能被改变或删除,即不能被加排他DDL锁。

DDL锁的类型与特征如表所示。

DDL锁很少会在系统里引起争用,因为它们的保持时间都非常短暂。但DDL锁的存在却不容忽视,尤其是在申请排他DDL锁时。

2、DML

当用户发布DML(Data Manipulation Language)语句(如insert、update、delete)时会对涉及的对象加DML锁。由于DML语句涉及的是数据操作,所以该锁也被称为数据锁。

DML锁能防止多个事务并发访问数据时,对数据的一致性和完整性的破坏。

根据锁定的粒度和意向,DML锁有几种模式。在执行Lock Table语句或执行不同的DML语句时会加不同模式的DML锁。当一个事务在一个表上加了某种模式的DML锁之后,另一个事务在该表上所能执行的DML操作会受到限制,如下表所示。其中有的锁模式有2个名称,这是因为不同的Oracle版本在提到它们时使用了不同的表示方法。

三、死锁现象及其解决

死锁是一种比较严重的、特殊的锁争用类型。在这种锁争用中,两个或两个以上的用户正在等待对方锁定的资源。因此,如果不进行某种干预,任意一个事务都无法完成。

假设当前有两个会话,分别执行的事务如图所示。显然这两个会话之间由于互相锁定了对方所需要锁定的对象,所以发生了死锁。

“提示”Oracle提供了有效的死锁检测机制,周期性地(通常只有几秒钟)诊断系统中有无死锁,并提示用户。

当Oracle检测到死锁后,会在预警文件和跟踪文件中记录下死锁的信息,在跟踪文件中详细地记录了检测到死锁的时间、被死锁的语句、阻塞者会话、等待者会话、操作系统用户的信息(如用户名、用户所在的计算机、用户使用的应用程序)等有助于确定死锁及其处理方法的信息。

即使Oracle为会话A提示了检测到死锁的信息,并且回退了会话A的第2个update语句,但会话A仍然在第1个update语句上保持着锁,并阻塞了会话B的第2个update语句.

当出现检测到死锁的信息后,用户自己(或DBA通知相应的用户)执行commit语句或rollback语句,使事务结束,释放所加的锁。还可以使用 ALTER SYSTEM KILL SESSION 'sid, serial#' 语句来杀死会话,强行解决锁争用。

ORACLE 中的 锁 介绍的更多相关文章

  1. Oracle中的锁

    Oracle中的锁 锁是一种机制,多个事务同时访问一个数据库对象时,该机制可以实现对并发的控制 按照用户系统锁可以分为自动锁和显示锁. 自动锁(系统上锁):DML锁.DDL锁.systemlocks锁 ...

  2. 事务的隔离级别以及oracle中的锁

    事务的概念及特性 事务,一般是指要做的或所做的事情.在计算机术语中是指访问并可能更新数据库中各种数据项的一个程序执行单元(unit). 例如:在关系数据库中,一个事务可以是一条SQL语句,一组SQL语 ...

  3. Oracle中rownum原理介绍

    rownum原理如下:1.执行查询操作2.将第一行的row num置为13.将得到的行的row num与条件相比较,如果不匹配,则抛弃行,如果匹配,则返回行4.oracle获取下一行,然后将rownu ...

  4. oracle中print_table存储过程介绍

    一直以来,觉得MySQL中使用\G参数改变输出结果集的显示方式非常好用,尤其是在命令行界面.但是ORACLE数据库没有这个功能,今天在搜索到Tom大师的一篇博文时,发现大师用一个存储过程print_t ...

  5. Oracle中SQL语言介绍以及基本用法

    一.SQL语言支持如下类别命令 1.数据定义语言(DDL):CREATE(创建).ALTER(更改) 和 DROP(删除)命令 1.1  CREATE (创建表,表空间,用户, 索引, 视图, 同义词 ...

  6. oracle中print_table存储过程实例介绍

    oracle中pro_print_table存储过程实例介绍 存储过程(Stored Procedure),就是一组用于完成特定数据库功能的SQL语句集,该SQL语句集经过编译后存储在数据库系统中.这 ...

  7. Oracle中的NVL函数

    Oracle中函数以前介绍的字符串处理,日期函数,数学函数,以及转换函数等等,还有一类函数是通用函数.主要有:NVL,NVL2,NULLIF,COALESCE,这几个函数用在各个类型上都可以. 下面简 ...

  8. [转载]Oracle中的NVL函数

    Oracle中函数以前介绍的字符串处理,日期函数,数学函数,以及转换函数等等,还有一类函数是通用函数.主要有:NVL,NVL2,NULLIF,COALESCE,这几个函数用在各个类型上都可以. 下面简 ...

  9. 问题:oracle nvl;结果:Oracle中的NVL函数

    Oracle中的NVL函数 (2012-11-30 13:21:43) 转载▼ 标签: nvl oracle 分类: Oracle Oracle中函数以前介绍的字符串处理,日期函数,数学函数,以及转换 ...

随机推荐

  1. J2EE开发框架搭建(2) - springmvc4 + spring4 + hibernate4 整合

    1. 打开hqhop-framework-parent项目下的pom.xml文件.加入springmvc4 , spring4 , hibernate4 ,以及数据源druid的依赖包,插件,依赖包版 ...

  2. Swift - 使用网格(UICollectionView)的自定义布局实现复杂页面

    网格UICollectionView除了使用流布局,还可以使用自定义布局.实现自定义布局需要继承UICollectionViewLayout,同时还要重载下面的三个方法: 1 2 3 4 5 6 7 ...

  3. 虚继承之单继承的内存布局(VC在编译时会把vfptr放到类的头部,这和Delphi完全一致)

    C++2.0以后全面支持虚函数与虚继承,这两个特性的引入为C++增强了不少功能,也引入了不少烦恼.虚函数与虚继承有哪些特性,今天就不记录了,如果能搞了解一下编译器是如何实现虚函数和虚继承,它们在类的内 ...

  4. 14.3.2.3 Consistent Nonlocking Reads 一致性非锁定读

    14.3.2.3 Consistent Nonlocking Reads 一致性非锁定读 一致性读 意味着 InnoDB 使用多版本来保护查询一个数据库在当前时间点的快照. 查询看到被事务做出的修改, ...

  5. Detours信息泄漏漏洞

    v\:* {behavior:url(#default#VML);} o\:* {behavior:url(#default#VML);} w\:* {behavior:url(#default#VM ...

  6. phprpc 使用实例(同时有Java、Android和Delphi客户端的例子)

    PHPRPC 是一个轻型的.安全的.跨网际的.跨语言的.跨平台的.跨环境的.跨域的.支持复杂对象传输的.支持引用参数传递的.支持内容输出重定向的.支持分级错误处理的.支持会话的.面向服务的高性能远程过 ...

  7. SQL SERVER CHARINDEX函数

    CHARINDEX函数经常常使用来在一段字符中搜索字符或者字符串.假设被搜索的字符中包括有要搜索的字符,那么这个函数返回一个非零的整数,这个整数是要搜索的字符在被搜索的字符中的開始位数.即CHARIN ...

  8. Android 开源项目android-open-project工具库解析之(一) 依赖注入,图片缓存,网络相关,数据库orm工具包,Android公共库

    一.依赖注入DI 通过依赖注入降低View.服务.资源简化初始化.事件绑定等反复繁琐工作 AndroidAnnotations(Code Diet) android高速开发框架 项目地址:https: ...

  9. Android开发人员必知的开发资源

    developer.android.com 官方开发人员网站推荐资源 在动手编写第一个 Android 应用之前,用心读一读 Android Design 章节.尤其是以下的这些文章: Devices ...

  10. Linux从用户层到内核层系列 - GNU系列之glibc介绍

    题记:本系列文章的目的是抛开书本从源代码和使用的角度分析Linux内核和相关源代码,byhankswang和你一起玩转linux开发 轻松搞定TCP/IP协议栈,原创文章欢迎交流, byhankswa ...