首页 > 代码库 > 定位数据库死锁,和初步解决死锁办法(后发制人)
定位数据库死锁,和初步解决死锁办法(后发制人)
1.目前我只是在sql 2008上实验成功:
在数据库开启跟踪标识:
DBCC TRACEON(1204,-1)
DBCC TRACEON(1222,-1)
这两个跟踪标记都是将死锁写到错误日志中,不过1204是以文本格式进行,而1222是以XML格式保存。
开启后通过查看数据库日志文件就可以找到是那个语句引发死锁。
1.模拟一个死锁:
1 DBCC TRACEON(1204,-1) 2 DBCC TRACEON(1222,-1) 3 4 CREATE TABLE Lock1(C1 int default(0)); 5 CREATE TABLE Lock2(C1 int default(0)); 6 INSERT INTO Lock1 VALUES(1); 7 INSERT INTO Lock2 VALUES(1); 8 9 将以下脚本分别打开到两个查询分析器窗口中:10 11 1.12 Begin Tran13 Update Lock1 Set C1=C1+1;14 WaitFor Delay ‘00:01:00‘;15 SELECT * FROM Lock216 Rollback Tran;17 18 2.19 Begin Tran20 Update Lock2 Set C1=C1+1;21 WaitFor Delay ‘00:01:00‘;22 SELECT * FROM Lock123 Rollback Tran;
依次执行完毕后,稍后片刻会出现死锁详情:
此时我们查看数据库日志:
此时死锁有了,数据库日志也有了。万事俱备咱开始结合死锁说明和日志着手分析:
死锁通俗说明:
在死锁发生的时候,进程为54执行的sql语句和另外一个进程的sql语句共同光合作用下产生了死锁,但是系统会选择一个轻量级的进程当做牺牲品,干掉了这个进程,但是由于造成死锁的恰恰是另外一个进程的sql语句。所以必须首先找到另外一个进程的sql语句,死锁解决就指日可待了。
结合当前死锁说明,我们就知道,进程为54的这条不是造成死锁的原因,那么就是 日志文件里面进程为53的这条sql语句诱发了死锁。
1 进程53所执行的sql语句:2 3 Begin Tran4 Update Lock1 Set C1=C1+1;5 WaitFor Delay ‘00:01:00‘;6 SELECT * FROM Lock27 Rollback Tran;
针对症结对症下药:
结合网上的资料,使用with(nolock)来解决。with(nolock)只是针对select引发的死锁有效,并且对有可能产生的脏读不是很在意的时候可以采用此办法,否则还得另寻他路。
具体如下:
Begin Tran Update Lock1 Set C1=C1+1; WaitFor Delay ‘00:01:00‘; SELECT * FROM Lock2 whth(nolock)Rollback Tran;
此时在将模拟死锁的sql脚本在如法炮制一次你会发现,就不会出现死锁了如下所示:
以上针对sql的见解纯属本人愚见,同时也希望能够抛砖引玉。有说的不对的地方,还望大家给小弟说一下。
最后说明一下:
不足:这种方式只能坐等死锁发生后,开始着手解决。从战略上属于后发。
定位数据库死锁,和初步解决死锁办法(后发制人)
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。