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

oracle的死锁实验

2014-09-16 15:46 155 查看
oracle当中的deadlock死锁,产生原因是由于两个会话互相征用对方占用的资源造成的。

当oracle检测到死锁时,会自动驳回一方请求冲突资源的请求,并报出

ORA-00060: 等待资源时检测到死锁  的错误

--实验模拟死锁产生过程

实验环境:linux redhat 5, oracle 11gR2, 数据库用户:scott

1、准备:创建1张测试表

SQL> create table lock1(id number(2),comm varchar2(10));      

Table created.

2、准备:向两张表中分别插入两条数据

SQL> insert into lock1 values (1,'a');

1 row created.

SQL> insert into lock1 values (2,'b');

1 row created.

SQL> commit;

Commit complete.

3、新开一个session,两个session中分别查询各自的sid

session1:

SQL> select sid from v$mystat where rownum<2;

       SID

----------

       125

session2:

SQL> select sid from v$mystat where rownum<2;

       SID

----------

        21

4、在两个session中分别执行update语句,不提交

session1:

SQL> update lock1 set comm='sess1' where id=1;

1 row updated.

session2:

SQL> update lock1 set comm='sess2' where id=2;

1 row updated.

5、此时两个session的锁状态:

select * from v$lock where sid in (125,21);

ADDR     KADDR           SID TY        ID1        ID2      LMODE    REQUEST  CTIME      BLOCK

-------- -------- ---------- -- ---------- ---------- ---------- ----------  ---------- ----------

4448DD84 4448DDC4        125 TX      65564       2273          6          0   118          0

444B3B14 444B3B54         21 TX     262167       2308          6          0   111          0

这两个session分别用行锁 TX 独占LMODE 6 锁住了两行

6、接下来,在session1中尝试更新记录2,此时会卡住,然后查看锁状态

session1

update lock1 set comm='sess1' where id=2;

select * from v$lock where sid in (125,21);

ADDR     KADDR           SID TY        ID1        ID2      LMODE    REQUEST  CTIME      BLOCK

-------- -------- ---------- -- ---------- ---------- ---------- ----------  ---------- ----------

45A87528 45A87554        125 TX     262167       2308          0      6        42          0

发现session1新增了一条记录,请求LMODE 6 的行锁

7、再对session2尝试更新记录1,也就是session1占用的记录

session2:

update lock1 set comm='sess2' where id=1;

此时session2会卡住,而在session1中则会报出死锁错误:

session1:

SQL> update lock1 set comm='sess1' where id=2;

update lock1 set comm='sess1' where id=2

       *

ERROR at line 1:

ORA-00060: deadlock detected while waiting for resource

再次查看锁状态发现session1之前请求的记录没有了,新增了session2的请求记录:

ADDR     KADDR           SID TY        ID1        ID2      LMODE    REQUEST  CTIME      BLOCK

-------- -------- ---------- -- ---------- ---------- ---------- ----------  ---------- ----------

45A87A24 45A87A50         21 TX      65564       2273          0          6   101          0

8、此时session1并没有被自动rollback,而session2还继续卡着。

此时对session1执行commit或rollback,session2就会立刻执行完成。

结论:

oracle的死锁产生是由于两个session互相争用对方占有的资源导致的。而oracle会自动检测死锁的产生

一旦检测到死锁的发生,oracle会自动解除一个session的请求。并返回一个ora-600的错误。但并不会自动rollback这个

session,而另外的等待session还是会继续等待,直到另一个session rollback或者commit为止。

参考资料:
http://blog.itpub.net/17203031/viewspace-682115/
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息