知识大全 解析Oracle多粒度锁的验证步骤

Posted 操作

篇首语:熟读唐诗三百首,不会作诗也会吟。本文由小常识网(cha138.com)小编为大家整理,主要介绍了知识大全 解析Oracle多粒度锁的验证步骤相关的知识,希望对你有一定的参考价值。

解析Oracle多粒度锁的验证步骤  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!

  创建测试表

  create >aaa@AAA US ORACLE >create table test (a number b number)

  表已创建

   对于未提交的insert操作

  insert >aaa@AAA US ORACLE >insert into test values( )

  已创建 行

   cellPadding= width= % bgColor=#cccccc> f f >

  SQL> select * from v$lock;   ADDR KADDR SID TYPE ID  D  LMODE REQUEST CTIME BLOCK    AB   AB A    TM               AF   AF    TX           

  可见 对于未提交的insert操作 会产生两个锁 其类型(TYPE)分别为TM和TX 也就是表级意向锁和事务锁

  表级意向锁的模式(LMODE)为 表示是row exclusive 即表示此表中的某行获得了行排他锁

  事务锁的模式(LMODE)为 表示是exclusive 即排他锁 表示此事务获得了排他锁

  BLOCK表示此锁是否阻塞了其它的锁 即发生死锁 此处没有

   对于提交的insert操作

  mit >aaa@AAA US ORACLE >mit

  提交完成

   cellPadding= width= % bgColor=#cccccc> f f >

  SQL> select * from v$lock;

  ADDR KADDR SID TYPE ID D LMODE REQUEST CTIME BLOCK

  此处已没有记录 说明在提交后 即完成了锁的释放

   对于未提交的update操作

  update >aaa@AAA US ORACLE >update test set a= where a=

  已更新 行

   cellPadding= width= % bgColor=#cccccc> f f >

  SQL> select * from v$lock;   ADDR KADDR SID TYPE ID  D  LMODE REQUEST CTIME BLOCK    AB   AB A    TM               AF   AF    TX           

  可见update操作所引起的锁的信息完全等同于insert操作……

   对于提交的update操作

  mit >aaa@AAA US ORACLE >mit

  提交完成

   cellPadding= width= % bgColor=#cccccc> f f >

  SQL> select * from v$lock;   ADDR KADDR SID TYPE ID  D  LMODE REQUEST CTIME BLOCK

  此处已没有记录 说明在提交后 即完成了锁的释放

   对于select操作

   cellPadding= width= % bgColor=#cccccc> f f >

  aaa@AAA US ORACLE >select * from test where a= ;   A B             SQL> select * from v$lock;   ADDR KADDR SID TYPE ID  D  LMODE REQUEST CTIME BLOCK

  此处已没有记录 说明select操作不会引起任何锁

  这是与sql server等数据库不同的 这些数据库select操作也会引起锁 以取得一致读

  而oracle是通过回滚机制实现一致读的 所以不需要引入锁机制 这极大增强了oracle的并发度

   for update操作

   cellPadding= width= % bgColor=#cccccc> f f >

  aaa@AAA US ORACLE >select * from test for update;   A B             SQL> select * from v$lock;   ADDR KADDR SID TYPE ID  D  LMODE REQUEST CTIME BLOCK    AB   AB A    TM               AF   AF    TX           

  可见 for update操作会引起两个锁 分别是表级意向锁(TM)和事务锁(TX)

  表级意向锁锁定模式为 (row share) 这表示属于此表中的某行获得了共享锁 相比较DML操作 此处锁级别低了一级 DML的是 其实在oracle中没有行级共享锁

  TX的锁定模式为 表示行级排他锁 这与DML的效果一致

   for update操作 mit后

  当mit后 就会发现锁已被释放

   for update与update互锁问题

   ) session 中

   cellPadding= width= % bgColor=#cccccc> f f >

  aaa@AAA US ORACLE >select * from test for update;   A B          

   ) session 中

  update >aaa@AAA US ORACLE >update test set a= where a=

  此时 这条语句处于阻塞状态 说明等待锁

  查看锁

   cellPadding= width= % bgColor=#cccccc> f f >

  SQL> select * from v$lock;   ADDR KADDR SID TYPE ID  D  LMODE REQUEST CTIME BLOCK    D CCC  D CDC   TX               AB   AB C   TM               AB   AB A    TM               AF   AF    TX           

  发现有两个会话处于有锁的活动

  发出for update操作的session (sid= )的有模式为 (row share)的行级共享意向表级锁 模式为 (exclusive)行级排他锁

  发出update操作的session (sid= )的模式为 (row exclusive)的行级排他意向锁 模式为 (None)的行级锁

  这说明 第二个session(sid= )由于是后发出的操作 它会首先去检索将要操作的表是否存在锁 此处由于存在 故就堵塞了 所以没有获得行级锁

  这也就说 两个session在检测操作对象是否处于被锁状态时 是首先检测其表级锁 这就避免了去检测没一行的锁 这就提升了性能

  像这里的情况 我们所操作的对象是行 但所利用的检测锁机制是在表级

  同时 会发现session (sid= )的TX锁的BLOCK为 这表示此锁堵住了另外的锁 同时我们会看到session (sid= )的TX锁等待的对象ID 和ID 与sid= 的相同 这说明sid= 的堵住了sid= 的

   rollback第一个会话的for update操作

  rollback >aaa@AAA US ORACLE >rollback

  回退已完成

  查看锁

   cellPadding= width= % bgColor=#cccccc> f f >

  SQL> select * from v$lock;   ADDR KADDR SID TYPE ID  D  LMODE REQUEST CTIME BLOCK    AB   AB C   TM               AE B   AE BC   TX           

  可见 第一锁的信息已没有

  此时只有session 的锁的信息 而且session 已获得锁

  如果再将session 进行回滚 就会发现session 的锁也没有了

   实体完整性引发的锁阻塞

  在具有primary key约束的表中 在两个session中插入同样的记录

  alter >aaa@AAA US ORACLE >alter table test add constraint pk_a primary key(a)

  表已更改

  Session 中

  insert >aaa@AAA US ORACLE >insert into test(a) values( )

  已创建 行

  Session 中

  insert >aaa@AAA US ORACLE >insert into test(a) values( )

  session 处于阻塞状态

  可见 在session 没有提交的情况 实体完整性约束就会阻塞住session

  查看锁

   cellPadding= width= % bgColor=#cccccc> f f >

  SQL> select * from v$lock;   ADDR KADDR SID TYPE ID  D  LMODE REQUEST CTIME BLOCK    D CCC  D CDC   TX               AE B   AE BC   TX               AB   AB C   TM               AB   AB A    TM               AE C  AE A    TX           

  可见 session (sid= )已获得TM和TX锁 并且阻塞住了其它的锁

  session (sid= )被阻塞

  可以发现 session 已获得了行排他锁

   AE B AE BC TX

  已经完全分配了新的事务 所以session 不是被堵在和session 竞争同一个数据块上(如上面的例子) 而是被堵在了完整行约束上

   D CCC D CDC TX

  这个锁请求的类型为 (share)

  Sessio

  rollback >aaa@AAA US ORACLE >rollback

  回退已完成

  Session

  insert >aaa@AAA US ORACLE >insert into test(a) values( )

  已创建 行

   cellPadding= width= % bgColor=#cccccc> f f >

  ADDR KADDR SID TYPE ID  D  LMODE REQUEST CTIME BLOCK    AB   AB C   TM               AE B   AE BC   TX           

  可见 session 所持有的锁剩余两个 那个原来等待session 的锁已释放

   参照完整性引发的锁阻塞

  create >aaa@AAA US ORACLE >create table test_child(c number a number not null constra

  int pk_a_ref references test(a))

  表已创建

  insert >aaa@AAA US ORACLE >insert into test(a) values( )

  已创建 行

  Session

   cellPadding= width= % bgColor=#cccccc> f f >

  aaa@AAA US ORACLE >@showlockedobj   O_NAME SID LOCK_TYPE OBJECT_NAME XIDUSN XIDSLOT   XIDSQN                AAA   Row Exclusive TEST         AAA   Row share TEST_CHILD      

  可以发现 有两个对象被锁住 TEST和TEST_CHILD

   cellPadding= width= % bgColor=#cccccc> f f >

  aaa@AAA US ORACLE >@showlocks   SID TYPE ID  ID  LOCK_TYPE REQUEST CTIME   BLOCK                    TM     Row Exclusive           TM     Row share           TX     Exclusive      

  可见有三个锁

   cellPadding= width= % bgColor=#cccccc> f f >

  SQL> select object_name from dba_objects where object_id= ;   OBJECT_NAME      TEST   SQL> select object_name from dba_objects where object_id= ;   OBJECT_NAME      TEST_CHILD

  可见 除了TEST表需要的TM和TX锁外

  还同时将TEST_CHILD表锁住了 其锁类型为Row share

  session

  insert >aaa@AAA US ORACLE >insert into test_child(c a) values( )

  插入外键值为 的 语句的执行会停顿

   cellPadding= width= % bgColor=#cccccc> f f >

  aaa@AAA US ORACLE >@showlockedobj   O_NAME SID LOCK_TYPE OBJECT_NAME XIDUSN XIDSLOT   XIDSQN                 AAA   Row share TEST         AAA   Row Exclusive TEST_CHILD         AAA   Row Exclusive TEST         AAA   Row share TEST_CHILD      

  这时会发现 被锁住的对象有 个 这是因为在子表中的插入同时会锁住父表和子表

   cellPadding= width= % bgColor=#cccccc> f f >

  aaa@AAA US ORACLE >@showlocks   SID TYPE ID  ID  LOCK_TYPE REQUEST CTIME   BLOCK                     TX     None           TM     Row share           TM     Row Exclusive           TX     Exclusive           TM     Row Exclusive           TX     Exclusive           TM     Row share      

  已选择 行

  分析锁的情况

  Session (sid= )有四个锁 分别是子表的TM和TX锁

   TM Row Exclusive

  

   TX Exclusive

  父表的TM和TX锁

   TX None

  

   TM Row share

  

  这是因为参照完整性需要父表在参照的过程中不能发生改变 所以要对父表加上这些限制

  Session

  rollback >aaa@AAA US ORACLE >rollback

  回退已完成

  Session

  insert >aaa@AAA US ORACLE >insert into test_child(c a) values( )

  insert into test_child(c a) values( )

  *

  ERROR 位于第 行

  ORA 违反完整约束条件 (AAA PK_A_REF) 未找到父项关键字

   更新子表时

  update >aaa@AAA US ORACLE >update test_child set a= where =

  已更新 行

   cellPadding= width= % bgColor=#cccccc> f f >

  aaa@AAA US ORACLE >@showlockedobj   O_NAME SID LOCK_TYPE OBJECT_NAME XIDUSN XIDSLOT   XIDSQN                 AAA   Row share TEST         AAA   Row Exclusive TEST_CHILD         aaa@AAA US ORACLE >@showlocks   SID TYPE ID  ID  LOCK_TYPE REQUEST CTIME   BLOCK                     TM     Row share           TM     Row Exclusive      

  可见 当更新子表时 会锁住父子两个表 即使实际上没有更新数据

   当更新父表时

  update >aaa@AAA US ORACLE >update test set a= where =

  已更新 行

   cellPadding= width= % bgColor=#cccccc> f f >

  aaa@AAA US ORACLE >@showlockedobj   O_NAME SID LOCK_TYPE OBJECT_NAME XIDUSN XIDSLOT   XIDSQN                 AAA   Row Exclusive TEST         aaa@AAA US ORACLE >@showlocks   SID TYPE ID  ID  LOCK_TYPE REQUEST CTIME   BLOCK                     TM     Row Exclusive         >   可见 更新父表只会锁住父表

   当父子两个表同时更新时

  session

  update >aaa@AAA US ORACLE >update test_child set a= where =

  已更新 行

  Session

  update >aaa@AAA US ORACLE >update test set a= where =

  session 会被锁住

   cellPadding= width= % bgColor=#cccccc> f f >

  aaa@AAA US ORACLE >@showlockedobj   O_NAME SID LOCK_TYPE OBJECT_NAME XIDUSN XIDSLOT   XIDSQN                 AAA   Row Exclusive TEST         AAA   None TEST_CHILD         AAA   Row Exclusive TEST         AAA   Row Exclusive TEST_CHILD         aaa@AAA US ORACLE >@showlocks   SID TYPE ID  ID  LOCK_TYPE REQUEST CTIME   BLOCK                     TM     Row Exclusive           TM     None           TM     Row Exclusive           TM     Row Exclusive      

  可见 会发生死锁 是由于第二个session 申请子表的share锁时发生的

   对外键建立索引

  create >aaa@AAA US ORACLE >create index idx_child on test_child(a)

  索引已创建

  当父子两个表同时更新时

  session

  update >aaa@AAA US ORACLE >update test_child set a= where =

  已更新 行

  Session

  update >aaa@AAA US ORACLE >update test set a= where =

  已更新 行

  可见 不会发生死锁

   cellPadding= width= % bgColor=#cccccc> f f >

  aaa@AAA US ORACLE >@showlockedobj   O_NAME SID LOCK_TYPE OBJECT_NAME XIDUSN XIDSLOT   XIDSQN                 AAA   Row Exclusive TEST         AAA   Row share TEST_CHILD         AAA   Row share TEST         AAA   Row Exclusive TEST_CHILD         aaa@AAA US ORACLE >@showlocks   SID TYPE ID  ID  LOCK_TYPE REQUEST CTIME   BLOCK                     TM     Row Exclusive           TM     Row share           TM     Row share           TM     Row Exclusive      

  可以发现 session 获得TEST_CHILD行级排他意向表锁 同时获得TEST表的行级共享排他意向锁

  session 获得TEST行级排他意向表锁 同时获得TEST_CHILD表的行级共享排他意向锁

  与上个例子相比 区别在于前面的例子中 session 获得TEST_CHILD和TEST行级排他意向表锁

  也就是说 对外键建立索引 可以防止两个表的死锁

   总结

  Oracle通过具有意向锁的多粒度封锁机制进行并发控制 保证数据的一致性 其DML锁(数据锁)分为两个层次(粒度) 即表级和行级 通常的DML操作在表级获得的只是意向锁(RS或RX) 其真正的封锁粒度还是在行级 另外 在Oracle数据库中 单纯地读数据(SELECT)并不加锁 这些都极大地提高了系统的并发程度

cha138/Article/program/Oracle/201311/18429

相关参考

知识大全 Oracle锁的运行机制原理的描述

Oracle锁的运行机制原理的描述  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  以下的文章抓哟

知识大全 查找 Oracle 用户锁的DLL SQL

查找Oracle用户锁的DLLSQL  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  查找Orac

知识大全 我对ORACLE数据锁的一点体会

我对ORACLE数据锁的一点体会  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  我对文章中意向锁

知识大全 Oracle数据库锁的常用类型有哪些

Oracle数据库锁的常用类型有哪些  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  此文章主要是

知识大全 Oracle数据库查找被锁以及解锁的解决办法

Oracle数据库查找被锁以及解锁的解决办法  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  or

知识大全 Oracle11gR1中细粒度访问网络服务

Oracle11gR1中细粒度访问网络服务  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  Ora

知识大全 Spring MVC验证的配置步骤

SpringMVC验证的配置步骤  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  这是我在练习MV

知识大全 更改Oracle用户名及外部用户验证授权

更改Oracle用户名及外部用户验证授权  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!我的测试机上

知识大全 oracle加锁

  加锁是为了防止一些操作而进行的比如说共享锁可以防止别的事务加上排他锁如果多个事物对同一张表都加上共享锁的话也就都不能修改了可以进行读操作如果只有一个事物加上共享锁是可以修改的  而排他锁呢则是不能

知识大全 取得Oracle认证的步骤

取得Oracle认证的步骤  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  Step—Select