前些天在同步数据的时候遇到了死锁,今天就结合一个简单的demo讲解一下死锁的产生、查询和处理方法。
首先,我们先来了解一下什么是死锁?死锁的本质是一种僵持状态,是多个主体对于资源的争用而导致的。而发
生死锁必须满足四个必要条件:
1、互斥条件
2、请求和等待
3、不剥夺权利
4、环路等待
下面通过一个日常生活中的例子来模拟一下:汽车对于道路的需求。这里汽车就是主体,而道路就是所谓的资
了。如下所示,在图的例子中每队汽车都占有一条道路,但都需要另外一队汽车所占有的另一条道路,因此互相阻
塞,谁都无法前行,因此造成了死锁。
对应死锁的四个条件如下
1)互斥条件
主体对于资源是独占的。图中的汽车道都是单行道,即每条汽车道在同一时刻只能跑一队汽车
2)请求和等待条件
指主体已经保持至少一个资源,但又提出了新的资源请求,而该资源已被其它主体占有,此时请求主体阻塞,但
又对自己已获得的其它资源保持不放。在图中,每队汽车已经占有了一条车道,又想获得另一条由其它车队占有的车
道,造成阻塞。
3)不剥夺条件
指的是主体已经获得的资源在完成其目标之前不能被释放。在图中,目标指的是汽车可以通过车道,不剥夺指的
是在完成这个目标之前,车队并不会让出其已占的车道。
4)环路等待条件
指在发生死锁时,必然存在一个主体——资源的环形链,即主体集合{P0,P1,P2,···,Pn}中的P0正在等待一
个P1占用的资源;P1正在等待P2占用的资源,……,Pn正在等待已被P0占用的资源。在图中可以看出,四条车道和
四队汽车正好符号环路等待的条件,车队1希望获得车队2占有的车道,车队2希望获得车队3占有的车道,车队3希望
获得车队4占有的车道,车队4反过来又希望获得车队1占有的车道,形成一个环路。
了解了什么是死锁,接下来就现场模拟一个死锁的产生。
1)更新操作
BEGIN TRANSACTION
USE testDB
UPDATE dbo.bird SET birdCount=20
WHERE code='2'
2)查询操作
SELECT * FROM dbo.bird
WHERE code='2'
这两个SQL语句是最平常的操作了,看起来没有什么。但是,更新事务占用一个session因为没有提交事务的操
作,该session一直在执行,而查询操作又重新生成了另一个session,这两个session都同时对表bird进行操作,这样
就产生了死锁。
查看死锁快捷键:Ctrl+2,得到的为所有死锁进程。为了数据库的安全性,我们只能操作自己的进程,因此还需
要知道PID。查询当前死锁进程的语句
select
request_session_id spid,
OBJECT_NAME(resource_associated_entity_id) tablename
from
sys.dm_tran_locks
where
resource_type='OBJECT'
这样我们就拿到了所有进程的ID和表名,接下来就可以杀死指定的死锁了。
KILL 56
参考文章链接:http://www.cnblogs.com/CareySon/archive/2012/09/19/2693555.html
http://www.cnblogs.com/aarond/p/deadlock.html