锁的种类,阻塞,死锁产生与解决办法。
TM锁的种类:
TM锁几种模式的互斥关系:
阻塞
定义:
当一个会话保持另一个会话正在请求的资源上的锁定时,就会发生阻塞。被阻塞的会话将一直挂起,直到持有锁的会话放弃锁定的资源为止。4个常见的dml语句会产生阻塞
INSERT
UPDATE
DELETE
SELECT…FOR UPDATE
——————————————————————————————————————————————————————————————
update 的阻塞 试验:
1. 获得会话sid
SQL> select sid from v$mystat where rownum=1; (首先update的会话sid)
SID
----------
1
SQL> select sid from v$mystat where rownum=1; (随后update的会话sid)
SID
----------
39
2. 操作表
SQL> select * from andy; (查看操作表)
ID
----------
1
SQL> update andy set id=2 where id=1; (首先,会话sid为1的update)
1 row updated.
SQL> update andy set id=2 where id=1; (随后,会话sid为39的update,执行后,发现被阻塞)
3. 查看会话锁冲突
SQL> select sid,type,lmode,id1,id2,request,block from v$lock where type in('TM','TX') order by 1,2;
SID TY LMODE ID1 ID2 REQUEST BLOCK
---------- -- ---------- ---------- ---------- ---------- ----------
1 TM 3 79729 0 0 0
1 TX 6 131072 1276 0 1
39 TM 3 79729 0 0 0
39 TX 0 131072 1276 6 0
解释说明:
SID:表示会话sid。
TY:表示锁的类型。
ID1:在TM一行中表示的是被修改表的标识(object_id)。
ID1:在TX一行中表示以十进制数值表示该事务所占用的回滚段号与该事务在该回滚段的事务表(Transaction table)中所占用的槽号(slot number,可理解为记录号)。其组成形式为: 0xRRRRSS 如: 1 TX 6 131072 1276 0 1
REQUEST:0表示的是已经获得锁。非0表示被阻塞,请求获得锁。 如:sid为1的会话,先update andy set id=2 where id=1;获得该行的TX锁,但为提交。然后sid为39的会话,再次andy set id=2 where id=1;请求获得该行的TX锁,但是该行TX锁被sid为1的会话占用,所以未获得该说,被阻塞,只能等待(sid为1提交与自己回滚)。
BLOCK:表示该锁是否阻塞了其他锁。 数字几代表阻塞了几
-- 验证 TM一行中表示的是被修改表的标识(object_id)。(确实如此)
SQL> select object_name from dba_objects where object_id=79729;
OBJECT_NAME
--------------------------------------------------------------------------------
ANDY
至此,阻塞试验完毕。
查询会话之间锁等待的关系
select a.sid holdsid,b.sid waitsid,a.type ,a.id1,a.id2,a.ctime from v$lock a,v$lock b
where a.id1=b.id1 and a.id2=b.id2 and a.block = 1 and b.block = 0 ;
HOLDSID WAITSID TY ID1 ID2 CTIME
---------- ---------- -- ---------- ---------- ----------
1 39 TX 458777 1066 503
1 51 TX 458777 1066 503
查被阻塞的会话
select * from v$lock where lmode=0 and type in ('TM','TX');
——————————————————————————————————————————————————————————
死锁-deadlock
定义:当两个用户希望持有对方的资源时就会发生死锁.
即两个用户互相等待对方释放资源时,oracle认定为产生了死锁,在这种情况下,将以牺牲一个用户作为代价,另一个用户继续执行,牺牲的用户的事务将回滚.
例子:
1:用户1对A表进行Update,没有提交。
2:用户2对B表进行Update,没有提交。
此时双反不存在资源共享的问题。
3:如果用户2此时对A表作update,则会发生阻塞,需要等到用户一的事物结束。
4:如果此时用户1又对B表作update,则产生死锁。此时Oracle会选择其中一个用户进行会滚,使另一个用户继续执行操作。
起因:
Oracle的死锁问题实际上很少见,如果发生,基本上都是不正确的程序设计造成的,经过调整后,基本上都会避免死锁的发生。
死锁试验:
SQL> select * from andy;
ID
----------
3
2
SQL> delete andy where id=2; (会话1)
1 row deleted.
SQL> delete andy where id=3; (会话2)
1 row deleted.
SQL> delete andy where id=3; (会话1)
delete andy where id=3
*
ERROR at line 1:
ORA-00060: deadlock detected while waiting for resource
SQL> delete andy where id=2; (会话2,阻塞状态)
死锁产生后,处理办法:
1)执行下面SQL,先查看哪些表被锁住了:
>select b.owner,b.object_name,a.session_id,a.locked_mode
from v$locked_object a,dba_objects b
where b.object_id = a.object_id;
2)查看引起死锁的会话
>select b.username,b.sid,b.serial#,logon_time
18:09:40 2 from v$locked_object a,v$session b
18:09:40 3 where a.session_id = b.sid order by b.logon_time;
3)查看被阻塞的会话
>select * from dba_waiters;
4)可以提交或回滚阻塞的话,释放锁或者杀掉ORACLE进程:
ALTER SYSTEM KILL SESSION 'SID,SERIAL#';
说明:
如果杀掉所有死锁相关的会话,则所有会话的事务回滚,相当于事务都为未执行。
如果杀掉报ORA-00060: deadlock detected while waiting for resource的会话,阻塞会话commit,阻塞会话将完成该会话的所有事务。
如果杀掉被阻塞的会话,报ORA-00060会话commit,则完成的事务是未产生死锁之前的事务。
如果报ORA-00060: deadlock detected while waiting for resource的会话进行rollback,阻塞会话commit,阻塞会话将完成该会话所有事务。
ok,结束。 转载请标明出处。