数据库中的死锁问题

  在数据库中经常会遇到这样的情况:一个主表A,一个子表B,B表中包含有A表的主键作为外键。当要插入数据的时候,我们会先插入A表,然后获得A表的Identity,再插入B表。如果要进行删除操作,那么就先删除子表B,然后再删除主表A。在程序设计中,对两个表的操作是在一个事务之中完成的。

  当系统使用频繁就会出现插入操作和删除操作同时进行的情况。这个时候插入事务会先将主表A放置独占锁,然后去访问子表B,而同时删除事务会对子表B放置独占锁,然后去访问主表A。插入事务会一直独占着A表,等待访问B表,删除事务也一直独占着B表等待访问A表,于是两个事务相互独占一个表,等待对方释放资源,这样就造成了死锁。


说道死锁问题的解决,一般情况下我们都是选择KILL进程,但如果不查出引起死锁的原因,死锁的现象则会频繁出现,其实只要通过查找引起死锁的操作,就可以方便的解决死锁。
  具体的解决方法如下:
  1.再死锁发生时,我们可以通过下面的语法,查询到引起死锁的操作

use master 
  
go 
  
declare @spid int,@bl int 
  
DECLARE s_cur CURSOR FOR 
  
select 0 ,blocked 
  
from (select * from sysprocesses where blocked>0 ) a 
  
where not exists(select * from (select * from sysprocesses where blocked>0 ) b 
  
where a.blocked=spid) 
  
union select spid,blocked from sysprocesses where blocked>0 
  
OPEN s_cur 
  
FETCH NEXT FROM s_cur INTO @spid,@bl 
  
WHILE @@FETCH_STATUS = 0 
  
begin 
  
if @spid =0 
  
select '引起数据库死锁的是: '+ CAST(@bl AS VARCHAR(10)) + '进程号,其执行的SQL语法如下' 
  
else 
  
select '进程号SPID:'+ CAST(@spid AS VARCHAR(10))+ '' + '进程号SPID:'+ CAST(@bl AS VARCHAR(10)) +'阻塞,其当前进程执行的SQL语法如下' 
  
DBCC INPUTBUFFER (@bl ) 
  
FETCH NEXT FROM s_cur INTO @spid,@bl 
  
end 
  
CLOSE s_cur 
  
DEALLOCATE s_cur 
  
exec sp_who2 
   
/*
  2.然后查找程序/数据库,此t_sql语法具体在什么地方使用。 
  3.分析已经找到的,解决问题。 
  EG:
   
*/
 
  
/* 
  ------------------------------------------------------- 
  引起数据库死锁的是: 71进程号,其执行的SQL语法如下 
  EventType Parameters EventInfo 
  -------------- ---------- ------------------------------ 
  Language Event 0 
  select * from test 
  insert test values(1,2) 
  (所影响的行数为 1 行) 
  DBCC 执行完毕。如果 DBCC 输出了错误信息,请与系统管理员联系。 
  ------------------------------------------------------------ 
  进程号SPID:64被进程号SPID:71阻塞,其当前进程执行的SQL语法如下 
  EventType Parameters EventInfo 
  -------------- ---------- --------------------------------- 
  Language Event 0 
  select * from test 
  insert test values(1,2) 
  (所影响的行数为 1 行) 
  DBCC 执行完毕。如果 DBCC 输出了错误信息,请与系统管理员联系。 
  ------------------------------------------------------------- 
  进程号SPID:65被进程号SPID:64阻塞,其当前进程执行的SQL语法如下 
  EventType Parameters EventInfo 
  -------------- ---------- ------------------------------------- 
  Language Event 0 begin tran 
  select * from test with (holdlock) 
  waitfor time '12:00' 
  select * from test 
  commit 
  (所影响的行数为 1 行) 
  DBCC 执行完毕。如果 DBCC 输出了错误信息,请与系统管理员联系。 
  ------------------------------------------------------- 
  进程号SPID:73被进程号SPID:64阻塞,其当前进程执行的SQL语法如下 
  EventType Parameters EventInfo 
  -------------- ---------- ------------------------------ 
  Language Event 0 begin tran 
  select * from test with (holdlock) 
  waitfor time '12:00' 
  select * from test 
  commit 
  (所影响的行数为 1 行) 
  DBCC 执行完毕。如果 DBCC 输出了错误信息,请与系统管理员联系。 
  
*/
  文章来源: baike.duba.net
posted @ 2009-07-01 11:23  大力  阅读(437)  评论(0编辑  收藏  举报