ITPub博客

首页 > Linux操作系统 > Linux操作系统 > Oracle LOCK内部机制及最佳实践系列(五)给出一个导致死锁的SQL示例

Oracle LOCK内部机制及最佳实践系列(五)给出一个导致死锁的SQL示例

原创 Linux操作系统 作者:leonarding 时间:2012-11-28 21:12:55 0 删除 编辑
给出一个导致死锁的SQL示例。

死锁定义:从广义上讲包括操作系统 应用程序 数据库,如果2个进程(会话)相互持有对方的资源,都一直等待对方释放,这种情况会造成死锁。
误解:会话的阻塞可不是死锁,因为其中有一个会话还是可以继续操作的。
释放:Oracle会自动检测死锁并强制干预释放

LEO1@LEO1> create table p1 ( x int primary key );       我们新建一个p1表,设置x字段为主键
Table created.
LEO1@LEO1> insert into leo1.p1 values(10);                 138会话插入的是10
1 row created.
LEO2@LEO1> insert into leo1.p1 values(20);                 156会话插入的是20
1 row created.
LEO1@LEO1> select sid,type,id1,id2,lmode,request,block from v$lock where type in ('TM','TX') order by 1,2;
       SID TYPE              ID1        ID2      LMODE    REQUEST      BLOCK
---------- ---------- ---------- ---------- ---------- ---------- ----------
       138 TM              73470          0          3          0          0
       138 TX             327713    1124          6          0          0             138有一个TX排他锁,但当前没有阻塞会话
       156 TM              73470          0          3          0          0
       156 TX             589825      945          6          0          0             156也有一个TX排他锁,但当前也没有阻塞会话
LEO1@LEO1> select object_name from dba_objects where object_id=73470;            看p1表上存在正常的TM  TX锁,都没有阻塞到对方的会话
OBJECT_NAME
--------------------------------------------------------------------------------
P1
LEO1@LEO1> insert into leo1.p1 values(20);              此时我在138会话上再插入20,发现hang住了不能前进,这是什么原因呢?我们看看v$lock视图
LEO1@LEO1> select sid,type,id1,id2,lmode,request,block from v$lock where type in ('TM','TX') order by 1,2;
       SID TY        ID1        ID2      LMODE    REQUEST      BLOCK
---------- -- ---------- ---------- ---------- ---------- ----------
       138 TM      73470          0          3          0          0
       138 TX     589825      945          0          4          0     这时138会话就继续插入了,但这个插入动作是成功的没有阻塞,而是由于138|156会话修改值的相同
       138 TX     327713    1124          6          0          0     违反了主键约束从而产生阻塞,实际是对修改值的相同产生了阻塞,所以申请的是4级锁,而非6级锁
       156 TM      73470          0          3          0          0
       156 TX     589825      945          6          0          1     156会话此时正在阻塞138会话,因为156会话的事务还没有完成还是一个未决状态

LEO2@LEO1> insert into leo1.p1 values(10);               我在156会话上也插入10,这时死锁的效果就出来了
LEO1@LEO1> select sid,type,id1,id2,lmode,request,block from v$lock where type in ('TM','TX') order by 1,2;
       SID TY        ID1        ID2      LMODE    REQUEST      BLOCK
---------- -- ---------- ---------- ---------- ---------- ----------
       138 TM      73470          0          3          0          0
       138 TX     327713    1124          6          0          1     138会话此时正在阻塞156会话,因为138会话的事务还没有完成还是一个未决状态
       156 TM      73470          0          3          0          0
       156 TX     327713    1124          0          4          0     实际上是对修改值的相同产生了阻塞,156会话正在申请4级锁
       156 TX     589825      945          6          0          0
LEO1@LEO1> insert into leo1.p1 values(20);               我们看一下138会话报错,Oracle自动检测死锁并强制干预释放
insert into leo1.p1 values(20)
                 *
ERROR at line 1:
ORA-00060: deadlock detected while waiting for resource(等待资源时检测到死锁->释放之)  这时请注意一下,只是释放掉了第一个锁定,但第二个锁定还在等待,所以我们要手工释放

小结:上面讲到了好几种锁的机制,我们崇尚的思想就是先要想一想为什么会出现锁,不出现行不行,锁的作用有哪些,这种启发式的思路能够让我们记忆深刻。
LOCK作用:独占业务资源  保证读一致性  维护事务完整性
LOCK宗旨:没有并发就没有锁,一个人操作数据库是不会产生锁的


Leonarding
2012.11.28
天津&winter
分享技术~成就梦想

Blog:

来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/26686207/viewspace-750184/ ,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论
刘盛,香港城市大学EMBA,现担任中国民生银行民生科技供应链金融事业部负责人,负责企业生态业务发展工作。 2016年8月12日刘盛受邀参加了由磐岩智慧在上海绿地万豪大酒店主办的“全球互联网金融创新论坛2016”,并作了“中国互联网金融信用体系建设与未来”主题演讲。

注册时间:2012-02-10

  • 博文量
    254
  • 访问量
    3355089