摘要:一旦申请成功,则会对将要修改的记录申请排他锁,如果此时其他会话正在修改该记录,那么等待其事务结束后再为修改的记录加上排他锁。该模式下不允许其他的并行会话对同一张表使用排他锁,但允许其利用语句或命令锁定同一张表中的其他记录。
本文以oracle数据库学习数据库锁 锁的分类
oracle中分为两种模式的锁,一种是排他锁(X锁),另一种是共享所(S锁).
排他锁,也可以叫写锁
共享所,也可以叫读锁
锁是实现并发的主要手段,在数据库中应用频繁,但很多都由数据库自动管理,当事务提交后会自动释放锁.
锁的类型Oracle为了使数据库实现高度并发访问,它使用了不同类型的锁来管理并发会话对数据对象的操作.Oracle的锁按作用对象不同分为如下几种类型.
DML锁: 该类型的锁被称为数据锁,用于保护数据
DDL锁: 可以保护模式中对象的结构
内部闩锁: 保护数据库的内部结构,完全自动调用
这里主要介绍下常用的DML锁,它主要保证了并发访问时数据的完整性.它又可以分为以下两种类型的锁:
1) 行级锁(TX),也可以称为事务锁.当修改表中某行记录时,需要对将要修改的记录加行级锁,防止两个事务同时修改相同记录,事务结束,该锁也会释放,是粒度最细的锁.该锁只能属于排他锁(X锁).
2) 表级锁(TM),主要作用书防止在修改表的数据时,表的结构发生变化.例如,会话S在修改表A的数据时,它会得到表A的TM锁,而此时将不允许其他会话对该表进行变更或删除操作. 该情况的验证过程如下:
UPDATE TABLE_NAME SET COLUMN= "test" WHERE ID = "id";
此时已经锁定该表,表级锁将不允许在事务结束前其他会话对表TABLE_NAME进行DDL操作.
其次,在执行DROP TABLE TABLE_NAME操作,执行后会提示ORA-00054错误.
原因是:
在执行DML操作时,数据库会先申请数据对象上的共享锁,防止其他会话对该对象执行DDL操作。一旦申请成功,则会对将要修改的记录申请排他锁,如果此时其他会话正在修改该记录,那么等待其事务结束后再为修改的记录加上排他锁。
ROW SHARE:行级共享锁(RS)。该模式下不允许其他的并行会话对同一张表使用排他锁,但允许其利用DML语句或lock命令锁定同一张表中的其他记录。SELECT...FROM FOR UPDATE 语句就是给记录加上了RS锁.
ROW EXCLUSEIVE, 行级排他锁(RX).该模式下允许并行会话对同一张表的其他数据进行修改,但不允许并行会话对同一张表使用排他锁.
SHARE,共享锁(S).该模式下,不允许会话更新表,但允许会话对表添加RS锁.
SHARE ROW EXCLUSIVE,共享行级排他锁(SRX).该模式下,不能对同一张表进行DML操作,也不能添加S锁.
EXCLUSIVE,排他锁(X).该模式下,其他的并行会话不能对表进行DML和DDL操作,该表只能读.
下表列出了以上5中模式相互之间的兼容关系.其中,✔表示相互兼容,×表示相互不兼容
RS | S | RX | SRX | X | ||
---|---|---|---|---|---|---|
RS | ✔ | ✔ | ✔ | ✔ | × | |
S | ✔ | ✔ | × | × | × | |
RX | ✔ | × | ✔ | ✔ | × | |
SRX | ✔ | × | × | × | × | |
X | × | × | × | × | × |
下面所示是Oracle中的各种SQL语句所产生的表级锁模式以及允许的锁定模式情况的汇总.
SQL语句 | 表锁模式 | RS | S | RX | SRX | X |
---|---|---|---|---|---|---|
SELECT ...FROM table | NONE | Y | Y | Y | Y | Y |
INSERT INTO ... | RX | Y | N | Y | N | N |
UPDATE table ... | RX | Y | N | Y | N | N |
DELETE FROM table ... | RX | Y | N | Y | N | N |
SELECT * FROM table FOR UPDATE | RX | Y | N | Y | N | N |
LOCK TABLE table IN ROW SHARE MODE | RS | Y | Y | Y | Y | N |
LOCK TABLE table IN ROW EXCLUSIVE MODE | RX | Y | N | Y | N | N |
LOCK TABLE table IN SHARE MODE | S | Y | N | N | N | N |
LOCK TABLE table IN SHARE ROW EXCLUSIVE MODE | SRX | Y | N | N | N | N |
LOCK TABLE table IN EXCLUSIVE MODE | X | N | N | N | N | N |
在Oracle中除了执行DML时自动为表添加TM锁外,也可以主动地为表添加TM锁,语法如下:
LOCK TABLE [schema.] table IN [EXCLUSIVE] [SHARE] [ROW EXCLUSIVE] [SHARE ROW EXCLUSIVE] [ROW SHARE* | SHARE UPDATE*] MODE [NOWAIT]
DDL锁也可以称为数据字典锁,主要作用是保护模式中对象的结构.当执行DDL操作时首先Oracle会自动地隐式提交一次事务,然后自动地给处理对象加上锁;当DDL结束时,Oracle会隐式地提交事务并释放DDL锁.与DML不同的是,用户不能显式的要求使用DDL锁.
DDL锁分为如下3类:
Exclusive DDL Lock,排他DDL锁定.如果对象加上了该类型的锁,那么对象不能被其他会话修改,而且该对象也不能再增加其他类型的DDL锁.如果是表,此时可以读取数据.
Shared DDL Lock,共享DDL锁定.保护对象的结构,其他会话不能修改该对象的结构,但是允许修改数据.
Breakable Parsed Lock,能打破的解析锁定.该类型的锁可以被打断,不能禁止DDL操作.
锁等待与死锁 锁等待在某些情况下由于占用的资源不能及时释放,而造成锁等待,也可以叫锁冲突.锁等待会严重地影响数据库性能和日常工作.
例如当一个会话修改表A的记录时,它会对该记录加锁,而此时如果另一个会话也来修改此记录,那么第二个会话将因得不到排他锁而一直等待,此时会出现执行SQL时数据库长时间没有响应的现象.直到第一个会话把事务提交,释放锁,第二个会话才能对数据进行操作.
下面为大家示例锁等待现象:
打开SLQ*PLUS窗口,修改PRODUCTINFO 表中PRODUCTID 字段为1的记录,脚本如下:
UPDATE PRODUCTINFO SET ORIGIN = "修改1" WHERE PRODUCTID = 1;
此时虽然提示已更新,但事务并没有提交.接下来进行第二步操作.
打开另一个SQL*PLUS 窗口,同样修改PRODUCTINFO 表中PRODUCTID字段为1的记录,脚本如下:
UPDATE PRODUCTINFO SET ORIGIN = "修改2" WHERE PRODUCTID = 1;
此时执行效果不会提示已更新,而是一直等待.
此时的情况是因为第一个会话封锁了该记录,但事务没有结束,锁不会释放,而这时第二个会话也要修改同一条记录,但它缺没有办法获得排他锁,所以只能等待.如果第一个会话修改数据的事务结束,那么第二个会话会结束等待.及时地结束事务是解决锁等待情况发生的有效方法.
死锁死锁的发生和锁等待不同,它是锁等待的一个特例,通常发生在两个或者多个会话之间.假设一个会话想要修改两个资源对象,可以是表也可以是字段,修改这两个资源的操作在一个事务当中,当它修改第一个对象时需要对其锁定,然后等待第二个对象,这时如果另外一个会话也需要修改这两个资源对象,并且已经获得对第二个对象的锁定,那么就会出现死锁,因为当前会话锁定了第一个对象等待第二个对象,而另一个会话锁定了第二个对象等待第一个对象.这样,两个会话都不能得到想要得到的对象,于是出现死锁.
这里例子就不在展示,大家可以自行试一试.实际开发中出现死锁情况大致有以下几种原因:
用户没有良好的编程习惯,偶尔会忘记提交事务,导致长时间占用资源.
操作的记录过多,而且操作过程中没有良好地对其分组.对于数据两很大的操作,可以将其分成几组提交事务,这样可以避免长时间的占用资源.
逻辑错误,两个会话都想得到已占有的资源.
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/17733.html
摘要:前情提要深入理解内存模型四锁的释放获取建立的关系锁是并发编程中最重要的同步机制。锁内存语义的实现本文将借助的源代码,来分析锁内存语义的具体实现机制。请看下篇深入理解内存模型六 前情提要 深入理解Java内存模型(四)—— volatile 锁的释放-获取建立的happens before 关系 锁是java并发编程中最重要的同步机制。锁除了让临界区互斥执行外,还可以让释放锁的线程向...
摘要:公平锁为了保证时间上的绝对顺序,需要频繁的上下文切换,而非公平锁会降低一定的上下文切换,降低性能开销。因此,默认选择的是非公平锁,则是为了减少一部分上下文切换,保证了系统更大的吞吐量。ReentrantLock简介ReentrantLock重入锁,是实现Lock接口的一个类,也是在实际编程中使用频率很高的一个锁, 支持重入性,表示能够对共享资源能够重复加锁,即当前线程获取该锁再次获取不会被阻...
阅读 1369·2019-08-30 12:54
阅读 1847·2019-08-30 11:16
阅读 1589·2019-08-30 10:50
阅读 2423·2019-08-29 16:17
阅读 1247·2019-08-26 12:17
阅读 1360·2019-08-26 10:15
阅读 2373·2019-08-23 18:38
阅读 772·2019-08-23 17:50