博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
oracle的锁机制
阅读量:5867 次
发布时间:2019-06-19

本文共 2475 字,大约阅读时间需要 8 分钟。

  hot3.png

oracle数据库是一个多用户使用的共享资源。当多个用户并发地存取数据时,在数据库中就会产生多个事务同时存取同一数据的情况。若对并发操作不加控制就可能会读取和存储不正确的数据,破坏数据库一致性。加锁是实现数据库并发控制的一个非常重要的技术,事务隔离级别也是基于锁实现的。

在数据库中有两种基本的锁类型:排它锁(Exclusive Locks,即X锁)和共享锁(Share Locks,即S锁)。当数据对象被加上X锁时,其他的事务不能对它读取和修改(也就是任何事务都不能再对当前数据对象加任何类型的锁)。加了S锁的数据对象可以被其它事务读取,但不能修改(表示其它事务只能对当前数据加S锁,而不能加X锁)。数据库利用这两种基本的锁类型来对数据库的事务进行并发控制。

oracle数据库的锁类型

根据保护的对象不同,oracle数据库锁可以分为以下几大类:DML锁(data locks,数据锁),用于保护数据的完整性;DDL锁(dictionary locks,字典锁),用于保护数据库对象的结构,如表、索引等的结构定义;内部锁和闩(internal locks and latches),保护数据库的内部结构。DML锁的目的在于保证并发情况下的数据完整性。在oracle数据库中,DML锁主要包括TM锁TX锁,其中TM锁称为表级锁TX锁称为事务锁或行级锁

TX锁(行级锁、事务锁)

许多对oracle不太了解的技术人员可能会以为每个TX锁代表一条被封锁的数据行,其实不然。TX的本义是Transaction(事务),当一个事务第一次执行数据更改(Insert、Update、Delete)或使用SELECT ... FOR UPDATE语句进行查询时,它即获得一个TX(事务)锁,直至该事务结束(执行COMMIT或ROLLBACK操作)时,该锁才被释放。所以,一个TX锁,可以对应多个被该事务锁定的数据行。

在oracle的每行数据上,都有一个标志位来表示该行数据是否被锁定。数据行上锁标志一旦被置位,就表明该行数据被加X锁oracle在数据行上没有S锁

TM锁(表级锁)

TM锁(表级锁)类型共有5种:共享锁(S锁)排它锁(X锁)行级共享锁(RS锁)行级排它锁(RX)共享行级排它锁(SRX锁)。下表为oracle数据库TM锁的相容矩阵(Y=YES,N=NO):

T1/T2                 
S              
X               
RS                 
RX                   
SRX              
-                     
S
Y
N
Y
N
N
Y
X
N
N
N
N
N
Y
RS
Y
N
Y
Y
Y
Y
RX
N
N
Y
Y
N
Y
SRX
N
N
Y
N
N Y
-
Y
Y
Y
Y
Y
Y

当oracle执行SELECT ... FROM UPDATE、INSERT、UPDATE、DELETE等DML语句时,系统自动在所要操作的表上申请表级RX锁注:SELECT ... FROM UPDATE在oracle 9i的早期版本中还是RS锁,之后就是RX锁了)。当表级锁获得后,系统再自动申请TX锁,并将实际锁定的数据行的锁标志位置位(指向该TX锁)。另一方面,程序或操作人员也可以通过LOCK TABLE语句来指定获得某种类型的TM锁。下表总结了oracle中各SQL语句产生TM锁的情况:

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
RX
RS、RX
lock table table_name in row share mode                                         
RS
RS、RX、S、SRX
lock table table_name in row exclsive 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

注意:在缺省情况下,单纯地读数据(SELECT)并不加锁另外,为什么SELECT FOR UPDATE、INSERT、UPDATE、DELETE,这四个语句为什么能相互阻塞?因为在它们获得RX表级锁之后,又申请了TX锁,也就是行级锁,行级锁只支持X锁,是个排它锁,所以阻塞了其它的事务

悲观锁与乐观锁

为了得到最大的性能,一般数据库都有并发机制,不过带来的问题就是数据访问的冲突。为了解决这个问题,大多数数据库用的方法就是数据的锁定,也就是我们上面讲的锁机制。数据的锁定分为两种:第一种叫悲观锁,第二种叫乐观锁。悲观锁顾名思义,就是对数据的冲突采取一种悲观的态度,也就是说假设数据肯定会冲突,所以在数据开始读取的时候就把数据锁定了。而乐观锁就是认为数据一般情况下不会造成冲突,所以在数据进行提交更新的时候,才会正式对数据的冲突与否进行检测,如果发现冲突了,则让用户返回错误的信息,让用户决定如何去做。

oracle使用悲观锁,从SQL语句上来看,就是使用 for update,for update nowait

oracle使用乐观锁,可以通过增加一列version或(timestamp)在应用程序中实现。当提交一条数据时,比较内存中数据和数据库中当前数据version或timestamp是否相同。如果不同,那么说明有冲突,不能提交,否则安全提交。另外,Oracle 10g 特性 ORA_ROWSCN,它好像也支持乐观锁

转载于:https://my.oschina.net/fhd/blog/285125

你可能感兴趣的文章
[android] 采用httpclient提交数据到服务器
查看>>
【转】Windows性能监控工具Perfmon的使用、性能指标分析
查看>>
解决 linux下编译make文件报错“/bin/bash^M: 坏的解释器:没有那个文件或目录” 问题...
查看>>
C# 整数转二进制字符串
查看>>
Unity投影器细节整理
查看>>
Storm集群部署
查看>>
jstat
查看>>
ECharts-百度地图使用
查看>>
Centos安装Mongodb
查看>>
asp.net mvc Post上传文件大小限制
查看>>
php模式设计之 单例模式
查看>>
Win10系统解决C盘分区限制一半的问题
查看>>
Symfony Composer icu requires lib-icu
查看>>
玩转X-CTR100 l STM32F4 l BMP280气压计传感器
查看>>
老程序员推荐的 10 个编程策略
查看>>
http响应详解_韩顺平PHP视频听课笔记
查看>>
车主如何不花一分钱不出一份力处理交通事故
查看>>
python 库安装方法及常用库
查看>>
cocos2dx 3.x(移动修改精灵坐标MoveTo与MoveBy)
查看>>
【215】◀▶ IDL 文件操作说明 (黑底)
查看>>