oracle 锁的介绍 (转)
本文转自:http://blog.csdn.net/gyb2013/article/details/6929697
一、什么是锁:
Oracle的锁机制是一种轻量级的锁定机制,不是通过构建锁列表来进行数据的锁定管理,而是直接将锁作为数据块的属性,存储在数据块首部。这个是通过ITL来实现的,一个事务要修改块中的数据,必须获得该块中的一个itl。关于itl(事务槽)的介绍可参考http://blog.csdn.net/gybyylx/article/details/6893639。
说明:在oracle数据库中,不存在真正意义上属于某个对象或数据的锁。oracle锁的信息是数据块的一个物理属性,而不是逻辑上属于某个表或某个行。
二、为什么需要锁:
oracle为什么好好的要搞一个锁(lock)机制出来呢?很简单,那是因为需要它。想想看我们自己家的门为什么要锁起来呢?这个我们肯定都知道怕家里的东西丢失或被别人拿走,如果没有别的人家世界就你一家那就没有必要锁门。oracle里锁也是一个道理,如果是单用户的系统,那完全没有必要这个锁,就是因为有多用户并发操作,我们为了确保资源的安全性(也就是oracle的数据完整性和一致性)才引申出这个锁出来。Oracle 利用其锁机制来实现事务间的数据并发访问及数据一致性。
三、锁的模式:
oracle有两种模式的锁:排他锁(exclusive lock,即X锁)和共享锁(share lock,即S锁)。
当数据对象被加上排它锁时,其他的事务不能对它读取(可以读取undo)和修改。加了共享锁的数据对象可以被其他事务读取,但不能修改。数据库利用这两种基本的锁类型来对数据库的事务进行并发控制。
四、锁的类型:
根据保护的对象不同,Oracle数据库锁可以分为以下几大类:
DML锁(data locks,数据锁):用于保护数据的完整性。
DDL锁(dictionary locks,字典锁):用于保护数据库对象的结构,如表、索引等的结构定义。
内部锁和闩(internal locks and latches):保护数据库的内部结构,例如,数据文件。内部锁及闩锁的管理完全由Oracle 自动完成。
1.DML锁:
DML锁的目的在于保证并发情况下的数据完整性,在Oracle数据库中,DML锁主要包括TM锁和TX锁,其中TM锁称为表级锁,TX锁称为事务锁或行级锁。DML 语句能够自动地获得所需的表级锁(TM)与行级(事务)锁(TX)。
a.表级锁(TM)
TM 锁用于确保在修改表的内容时,表的结构不会改变,例如防止在 DML 语句执行期间相关的表被移除。当用户对表执行 DDL 或 DML 操作时,将获取一个此表的表级锁。
Oracle的TM锁类型
锁模式 锁描述 解释 sql操作
0 none
1 NULL 空 Select
2 SS(Row-S) 行级共享锁,其他对象只能查询这些数据行 Select for update、Lock for update、Lock row share
3 SX(Row-X) 行级排它锁,在提交前不允许做DML操作 Insert、Update、Delete、Lock row share
4 S(Share) 共享锁 Create index、Lock share
5 SSX(S/Row-X) 共享行级排它锁 Lock share row exclusive
6 X(Exclusive) 排它锁 Alter table、Drop able、Drop index、Truncate table 、Lock exclusive
b.事务(行级)锁(TX)
事务发起第一个修改时会得到TX 锁(事务锁),而且会一直持有这个锁,直至事务执行提交(COMMIT)或回滚(ROLLBACK)。TX 锁用作一种排队机制,使得其他会话可以等待这个事务执行。事务中修改或通过SELECT FOR UPDATE 选择的每一行都会“指向”该事务的一个相关TX 锁。一个事务要修改块中的数据,必须获得该块中的一个itl,通过itl和undo segment header中的transaction table,可以知道事务是否处于活动阶段。事务在修改块时(其实就是在修改行)会检查行中row header中的标志位,如果该标志位为0(该行没有被活动的事务锁住),就把该标志位修改为事务在该块获得的itl的序号,这样当前事务就获得了对记录的锁定,然后就可以修改行数据了,这也就是oracle行锁实现的原理。
2.DDL锁:
在DDL 操作中会自动为对象加DDL 锁(DDL Lock),从而保护这些对象不会被其他会话所修改。例如,如果我执行一个DDL 操作ALTER TABLE T,表T 上就会加一个排他DDL 锁,以防止其他会话得到这个表的DDL锁和TM 锁。在DDL 语句执行期间会一直持有DDL 锁,一旦操作执行就立即释放DDL 锁。实际上,通常会把DDL 语句包装在隐式提交(或提交/回滚对)中来执行这些工作。由于这个原因,在Oracle 中DDL 一定会提交。每条CREATE、ALTER 等语句实际上都如下执行(这里用伪代码来展示):
Begin
Commit;
DDL-STATEMENT
Commit;
Exception
When others then rollback;
End;
因此,DDL 总会提交(即使提交不成功也会如此)。DDL 一开始就提交,一定要知道这一点。它首先提交,因此如果必须回滚,它不会回滚你的事务。如果你执行了DDL,它会使你所执行的所有未执行的工作成为永久性的,即使DDL 不成功也会如此。如果你需要执行DDL,但是不想让它提交你现有的事务,就可以使用一个自治事(autonomous transaction)。DDL锁分以下几种:
排他DDL 锁(Exclusive DDL lock):这会防止其他会话得到它们自己的DDL 锁或TM(DML)锁。这说明,在DDL 操作期间你可以查询一个表,但是无法以任何方式修改这个表。
共享DDL 锁(Share DDL lock):这些锁会保护所引用对象的结构,使之不会被其他会话修改,但是允许修改数据。
可中断解析锁(Breakable parse locks):这些锁允许一个对象(如共享池中缓存的一个查询计划)向另外某个对象注册其依赖性。如果在被依赖的对象上执行DDL,Oracle 会查看已经对该对象注册了依赖性的对象列表,并使这些对象无效。因此,这些锁是“可中断的”,它们不能防止DDL 出现。
3.闩(latch):是轻量级的串行化设备,用于协调对共享数据结构、对象和文件的多用户访问。关于latch后续单独介绍。
4.手动锁定:
1. 通过一条SQL 语句(例如select for update)手动地锁定数据。
2. 通过DBMS_LOCK 包创建我们自己的锁。
悲观封锁和乐观封锁
a、悲观封锁
悲观锁顾名思义,就是对数据的冲突采取一种悲观的态度,也就是说假设数据肯定会冲突,所以在数据开始读取的时候就把数据锁定住:
Select ..for update(nowait)
Select * from tab1 for update
用户发出这条命令之后,oracle将会对返回集中的数据建立行级封锁,以防止其他用户的修改。
如果此时其他用户对上面返回结果集的数据进行dml或ddl操作都会返回一个错误信息或发生阻塞。
1:对返回结果集进行update或delete操作会发生阻塞。
2:对该表进行ddl操作将会报:Ora-00054:resource busy and acquire with nowait specified.
原因分析
此时Oracle已经对返回的结果集上加了排它的行级锁,所有其他对这些数据进行的修改或删除操作都必须等待这个锁的释放,产生的外在现象就是其他的操作将发生阻塞,这个这个操作commit或rollback.
同样这个查询的事务将会对该表加表级锁,不允许对该表的任何ddl操作,否则将会报出ora-00054错误::resource busy and acquire with nowait specified.
b、乐观封锁
乐观锁就是认为数据一般情况下不会造成冲突,所以在数据进行提交更新的时候,才会正式对数据的冲突与否进行检测,如果发现冲突了,则让用户返回错误的信息,让用户决定如何去做。这里面有一种潜在的危险就是由于被选出的结果集并没有被锁定,是存在一种可能被其他用户更改的可能(丢失更新问题)。乐观锁和悲观锁各有优缺点,视具体实际情况来定。
关于oracle悲观锁和乐观锁的介绍可参考:http://blog.csdn.net/gybyylx/article/details/4474270
本文只是对oracle锁做了一个大概介绍,后续会对oracle锁机制做进一步的探讨。
oracle 锁的介绍 (转)的更多相关文章
- oracle锁等级以及解锁
以下是两遍关于锁的介绍的文章,第一篇介绍锁等级以及常用操作,第二篇主要介绍了oracle中两个用以查询数据库任意对象的两个视图 一: http://www.cnblogs.com/lguyss/arc ...
- 【锁】Oracle锁系列
[锁]Oracle锁系列 1 BLOG文档结构图 2 前言部分 2.1 导读和注意事项 各位技术爱好者,看完本文后,你可以掌握如下的技能,也可以学到一些其它你所不知道的知识,~O(∩_∩)O~: ...
- oracle锁表问题解决方法
详见:http://blog.yemou.net/article/query/info/tytfjhfascvhzxcytp52 Oracle数据库操作中,我们有时会用到锁表查询以及解锁和kill进程 ...
- oracle锁---原理篇
在现代的多用户多任务系统中,必然会出现多个用户同时访问共享的某个对象,这个对象可能是表,行,或者内存结构,为了解决多个用户并发性访问带来的数据的安全性,完整性及一致性问题,必须要有一种机制,来使对这些 ...
- Oracle 锁机制
本文参考自:ORACLE锁机制 1.oracle是一个多用户使用的共享资源,当多个用户并发的操作同一数据行时,那么在oracle数据库中就会存在多个事务操作统一数据行的操作,如果不对并发操作进行控制, ...
- oracle(enquences & latches )lock (oracle 锁大全)
资料来自官方文档: https://docs.oracle.com/database/121/CNCPT/consist.htm#CNCPT1333 https://docs.oracle.com/d ...
- Oracle优化器介绍
Oracle优化器介绍 本文讲述了Oracle优化器的概念.工作原理和使用方法,兼顾了Oracle8i.9i以及最新的10g三个版本.理解本文将有助于您更好的更有效的进行SQL优化工作. RBO优化器 ...
- Mysql锁机制介绍
Mysql锁机制介绍 一.概况MySQL的锁机制比较简单,其最显著的特点是不同的存储引擎支持不同的锁机制.比如,MyISAM和MEMORY存储引擎采用的是表级锁(table-level locking ...
- oracle常用视图介绍
oracle常用视图介绍---------------------2013/10/04(last updated) dba_开头: dba_users 数据库用户信息 dba_segm ...
随机推荐
- 带OUTPUT参数的CLR存储过程
前面写了一篇<带参数的CLR存储过程>http://www.cnblogs.com/insus/p/4373605.html ,如果我们需要创建一个带OUTPUT返回值. 实现它,可以先了 ...
- silverlight 4 tools for vs2010无法在vs2010 SP1上安装的解决办法
环境:英文版vs2010 sp1 + vs2013 RC 90天体验版 原来可以正常做silverilght 4 项目开发,今天因为vs2013 RC过了90天体验期,卸载时顺带把Silverlihg ...
- 扩展欧几里得算法(extgcd)
相信大家对欧几里得算法,即辗转相除法不陌生吧. 代码如下: int gcd(int a, int b){ return !b ? gcd(b, a % b) : a; } 而扩展欧几里得算法,顾名思义 ...
- 绝对干货:供个人开发者赚钱免费使用的一些好的API接口
不久前,我写了一篇文章,名为<科普技术贴:个人开发者的那些赚钱方式>,讲了一些个人开发者接私活和自己做软件加广告的一些科普知识.可是做软件,需要服务器,需要后台,对于一些小的开发者,想赚点 ...
- jni的使用方法
我们可以通过jni来调用c/c++程序,C/C++一般会被作为动态库的形式来供java程序调用 环境 操作系统:Centos6.7 java: openjdk7 依赖包:java7-devel(yum ...
- SSH框架 sequence diagram
- 1025基础REDIS
-- 登录AUTHPING -- 通用命令EXISTS KEY EXPIRE KEY seconds 为给定 KEY 设置过期时间 -- 字符SET runoobkey redisDEL runoob ...
- 1020关于mysql一个简单语句的执行流程
MySQL的语句执行顺序 转自http://www.cnblogs.com/rollenholt/p/3776923.html MySQL的语句一共分为11步,如下图所标注的那样,最先执行的总是FRO ...
- Easyui表单,文本框,下拉菜单三级联动练习代码
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding= ...
- iOS开发小技巧--即时通讯项目:使用富文本在UILabel中显示图片和文字;使用富文本占位显示图片
Label借助富文本显示图片 1.即时通讯项目中语音消息UI的实现,样式如图: 借助富文本在UILabel中显示图片和文字 // 1.创建一个可变的富文本 NSMutableAttributedStr ...