Oracle DML锁 机制探究

网友投稿 716 2022-10-27

本站部分文章、图片属于网络上可搜索到的公开信息,均用于学习和交流用途,不能代表睿象云的观点、立场或意见。我们接受网民的监督,如发现任何违法内容或侵犯了您的权益,请第一时间联系小编邮箱jiasou666@gmail.com 处理。

Oracle DML锁 机制探究

1.1. 锁的基本概念

锁的定义:锁(lock)机制用于管理对共享资源的并发访问,用于多用户的环境下,可以保证数据库的完整性和一致性。锁是防止访问相同资源的事务之间的破坏性,交互的机制。既可以是用户对象(例如表或行),也可以是对用户不可见的系统对象(例如共享数据结构和数据字典行)。锁的作用:在并发事务之间防止破坏性的交互作用,不需要用户的动作,自动使用最低的限制级别,在事务处理期间保持。为了确保并发用户在存取同一数据库对象时的正确性(即无丢失修改、可重复读、不读“脏”数据),数据库中引入了锁机制。基本的锁类型有两种:排它锁(Exclusive locks记为X锁)和共享锁(Share locks记为S锁)。

排它锁:若事务T对数据D加X锁,则其它任何事务都不能再对D加任何类型的锁,直至T释放D上的X锁;一般要求在修改数据前要向该数据加排它锁,所以排它锁又称为写锁。共享锁:若事务T对数据D加S锁,则其它事务只能对D加S锁,而不能加X锁,直至T释放D上的S锁;一般要求在读取数据前要向该数据加共享锁,所以共享锁又称为读锁。

1.2. Oracle 锁机制介绍

根据保护对象的不同,单实例Oracle数据库锁可以分为以下几大类: DML lock(data locks,数据锁):用于保护数据的完整性; DDL lock(dictionary locks,字典锁):用于保护数据库对象的结构(例如表、视图、索引的结构定义); internal locks,latches,mutex,pin:保护内部数据库结构;本文主要讨论DML(也可称为data locks,数据锁)锁。从封锁粒度(封锁对象的大小)的角度看,Oracle DML锁共有两个层次,即行级锁和表级锁。

1.3. 显式锁定和隐式锁定

1.3.1. 显式锁定

只有TM表锁。LOCK TABLE TABLE_NAME IN ROW SHARE MODE NOWAIT; --2:RSLOCK TABLE TABLE_NAME IN SHARE UPDATE MODE; --2:RSLOCK TABLE TABLE_NAME IN ROW EXCLUSIVE MODE NOWAIT; --3:RXLOCK TABLE TABLE_NAME IN SHARE MODE; --4:SLOCK TABLE TABLE_NAME IN SHARE ROW EXCLUSIVE MODE; --5:SRXLOCK TABLE TABLE_NAME IN EXCLUSIVE MODE NOWAIT; --6:X

1.3.2. 隐式锁定

隐式锁定:Select * from table_name……Insert into table_name……Update table_name……Delete from table_name……Select * from table_name for update

1.4. Oracle的TX锁(行级锁、事务锁)

许多对Oracle不太了解的技术人员可能会以为每一个TX锁代表一条被封锁的数据行,其实不然。TX的本义是Transaction(事务),当一个事务第一次执行数据更改(Insert、Update、Delete)或使用SELECT… FOR UPDATE语句进行查询时,它即获得一个TX(事务)锁,直至该事务结束(执行COMMIT或ROLLBACK操作)时,该锁才被释放。所以,一个TX锁,可以对应多个被该事务锁定的数据行。在Oracle的每行数据上,都有一个标志位来表示该行数据是否被锁定。Oracle不像其它一些DBMS(数据库管理系统)那样,建立一个链表来维护每一行被加锁的数据,这样就大大减小了行级锁的维护开销,也在很大程度上避免了其它数据库系统使用行级封锁时经常发生的锁数量不够的情况。

1.5. TM锁(表级锁)

1.5.1. 意向锁的引出

表是由行组成的,当我们向某个表加锁时,一方面需要检查该锁的申请是否与原有的表级锁相容;另一方面,还要检查该锁是否与表中的每一行上的锁相容。比如一个事务要在一个表上加S锁,如果表中的一行已被另外的事务加了X锁,那么该锁的申请也应被阻塞。如果表中的数据很多,逐行检查锁标志的开销将很大,系统的性能将会受到影响。为了解决这个问题,可以在表级引入新的锁类型来表示其所属行的加锁情况,这就引出了“意向锁”的概念。意向锁的含义是如果对一个结点加意向锁,则说明该结点的下层结点正在被加锁;对任一结点加锁时,必须先对它的上层结点加意向锁。如:对表中的任一行加锁时,必须先对它所在的表加意向锁,然后再对该行加锁。这样一来,事务对表加锁时,就不再需要检查表中每行记录的锁标志位了,系统效率得以大大提高。

1.5.2. 意向锁的类型

由两种基本的锁类型(S锁、X锁),可以自然地派生出两种意向锁:意向共享锁(Intent Share Lock,简称IS锁):如果要对一个数据库对象加S锁,首先要对其上级结点加IS锁,表示它的后裔结点拟(意向)加S锁;意向排它锁(Intent Exclusive Lock,简称IX锁):如果要对一个数据库对象加X锁,首先要对其上级结点加IX锁,表示它的后裔结点拟(意向)加X锁。另外,基本的锁类型(S、X)与意向锁类型(IS、IX)之间还可以组合出新的锁类型,理论上可以组合出4种,即:S+IS,S+IX,X+IS,X+IX,但稍加分析不难看出,实际上只有S+IX有新的意义,其它三种组合都没有使锁的强度得到提高(即:S+IS=S,X+IS=X,X+IX=X,这里的“=”指锁的强度相同)。所谓锁的强度是指对其它锁的排斥程度。这样我们又可以引入一种新的锁的类型共享意向排它锁(Shared Intent Exclusive Lock,简称SIX锁) :如果对一个数据库对象加SIX锁,表示对它加S锁,再加IX锁,即SIX=S+IX。例如:事务对某个表加SIX锁,则表示该事务要读整个表(所以要对该表加S锁),同时会更新个别行(所以要对该表加IX锁)。这样数据库对象上所加的锁类型就可能有5种:即S、X、IS、IX、SIX。具有意向锁的多粒度封锁方法中任意事务T要对一个数据库对象加锁,必须先对它的上层结点加意向锁。申请封锁时应按自上而下的次序进行;释放封锁时则应按自下而上的次序进行;具有意向锁的多粒度封锁方法提高了系统的并发度,减少了加锁和解锁的开销。

1.5.3. Oracle的TM锁(表级锁)

1.6. 锁转换和锁升级

数据库在必要时执行锁转换。在锁转换中,数据库自动将较低限制的表锁转换为较高限制的其它锁定。(锁转换不同于锁升级,锁升级发生在当某个粒度级别持有许多锁(例如行),数据库将其提高到更高粒度级别(例如表)) Oracle数据库永远不会升级锁。ORACLE的锁是block里面实现的,(SQLSERVER,DB2是内存里面实现的.内存实现有资源消耗问题,当内存不足会引发锁升级)但是Oracle不会发生锁升级。事务拥有在此事务内被插入(insert),更新(update),删除(delete)的数据行的排它行级锁(exclusive row lock)。对于数据行来说,排它行级锁已经是限制程度最高的锁,因此无需再进行锁转换(lock conversion)。

1.7. 实验探究

1.7.1. 同表操作同一行数据引发的锁阻塞

(此处省略修改同一数据行引发,现象于SELECT…FOR UPDATE基本相同)首先建立3个会话,其中两个(以下用session1、session2表示)以SCOTT用户连入数据库,以操作Oracle提供的示例表(DEPT、EMP);另一个(以下用session3表示)以SYS用户连入数据库,用于监控动态性能视图。

可以看到,Session1的事务所持有的锁已经释放,系统为Session 2的事务分配了回滚段,而其TX锁也已经获得。再将会话2的事务进行回滚。可以看到,TM与TX锁已全部被释放。

1.7.2. 深入探究:

根据官方文档归纳总结:v$lock视图列出当前系统持有的或正在申请的所有锁的情况,其主要字段说明如下:

因此transaction id就表示为(xidusn,xidslot,xidsqn)

1.7.3. 子表完整性引发所等待

1.7.4. 外键未加索引引发的锁阻塞

部分截取自互联网,如有侵权请与我联系。 wechat: 704012932 email: pkweibu@163.com CSDN: https://blog.csdn.net/weixin_37423880

上一篇:自动化GUI测试有很多可取的特点
下一篇:让我们来看看“hello world”风格的Cucumber的小例子
相关文章

 发表评论

暂时没有评论,来抢沙发吧~