您的位置:首页 > 数据库 > Oracle

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

2012-11-28 23:35 232 查看
给出一个导致死锁的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

本文出自 “刘盛分享技术~成就梦想” 博客,请务必保留此出处http://leonarding.blog.51cto.com/6045525/1073554
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐