锁实验

锁实验

1、使用Sql*plus,用system用户登录,打开4个session

2、在session1中创建一个测试表,插入2条记录

sql>create table t1 (id number, name varchar2(10));

sql>insert into t1 values(1,'A');

sql>insert into t1 values(2,'B');

sql>commit;

sql>update t1 set id=3 where id=1;

3、使用Sql*plus,在session2上执行

sql>update t1 set id=4 where id=1;

(该语句挂起)

4、在session 3 执行

sql>update t1 set id=5 where id=2;

(该语句能正常执行)

5、在session4中执行

sql>alter table t1 drop (name);

第 1 行出现错误:
ORA-00054: 资源正忙, 但指定以 NOWAIT 方式获取资源


6、在session1、session2、session3中分别提交事务

 sql>commit;

7、在session4中重新执行步骤5。

操作可以正常执行

8、在第一个会话中锁定整个表

sql>lock table t1 in exclusive mode;

9、在第二个会话中插入一条记录

sql>insert into t1 values(2);

出现等待

10、在第一个会话提交事务解锁,会话2操作正常

 sql>commit;


11、杀死持有锁的会话

  使用Sql*plus, 在 session 1中 执行

sql>update t1 set id=4 where id=1; update t1 set id=3 where id=1;

  使用Sql*plus,在session2上执行

sql>update t1 set id=4 where id=1;

使用Sql*plus,在session3上执行

SQL> select distinct s.sid,s.serial# from  v$session s, dba_waiters d where s.si
d=d.holding_session and sid not in (select waiting_session from dba_waiters);

SQL>ALTER SYSTEM KILL SESSION 'sid,serial#';

也可以在EM性能页中阻塞会话选项中处理

使用Sql*plus, 在 session 1中 执行 观察结果

SQL>SELECT * FROM t1;


总结:通过上面实验我们可以得出,在执行DML语句时,ORACLE会产生锁,一个是行级的锁,用来保护一行数据不能同时被两个或两个以上的会话修改,这是session2挂起的原因。
这个锁称为行级排他锁。除了行级排他锁之外,还产生一个表级共享锁,
我们在session4中修改表结构报错,表级共享锁不让其他会话获得表级排他锁,因为共享,所以session3可以正常操作。而当表获得表级排他锁时,任何DML操作都不可进行。
杀死会话是解决锁冲突的最后办法。

posted @ 2013-06-18 13:46  老猫-DB  阅读(276)  评论(0编辑  收藏  举报