为了账号安全,请及时绑定邮箱和手机立即绑定

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

标签:
Oracle


给出一个导致死锁的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:www.leonarding.com 

 

©著作权归作者所有:来自51CTO博客作者leonarding1的原创作品,如需转载,请注明出处,否则将追究法律责任

oracle阻塞死锁lock&latch原理与实践


点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消