锁实验
锁实验
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操作都不可进行。
杀死会话是解决锁冲突的最后办法。