http://tech.it168.com/db/s/2006-08-29/200608291525833.shtml
SQL Server数据库发生死锁时不会像ORACLE那样自动生成一个跟踪文件。有时可以在[管理]->[当前活动] 里看到阻塞信息(有时SQL Server企业管理器会因为锁太多而没有响应).
设定跟踪1204:
USE MASTER
DBCC TRACEON (1204,-1)
显示当前启用的所有跟踪标记的状态:
DBCC TRACESTATUS(-1)
取消跟踪1204:
DBCC TRACEOFF (1204,-1)
在设定跟踪1204后,会在数据库的日志文件里显示SQL Server数据库死锁时一些信息。但那些信息很难看懂,需要对照SQL Server联机丛书仔细来看。根据PAG锁要找到相关数据库表的方法:
DBCC TRACEON (3604)
DBCC PAGE (db_id,file_id,page_no)
DBCC TRACEOFF (3604)
请参考sqlservercentral.com上更详细的讲解.但又从CSDN学到了一个找到死锁原因的方法。我稍加修改, 去掉了游标操作并增加了一些提示信息,写了一个系统存储过程sp_who_lock.sql。代码如下:
ifexists (select*from dbo.sysobjects
where id=object_id(N'[dbo].[sp_who_lock]')
and OBJECTPROPERTY(id, N'IsProcedure')=1)
drop procedure [dbo].[sp_who_lock]
GO/********************************************************
// 创建 : fengyu 邮件 : maggiefengyu@tom.com
// 日期 :2004-04-30
// 修改 : 从http://www.csdn.net/develop/Read_Article.asp?id=26566
// 学习到并改写
// 说明 : 查看数据库里阻塞和死锁情况
********************************************************/use master
go
create procedure sp_who_lockasbegin
declare @spidint,@blint,
@intTransactionCountOnEntryint,
@intRowcountint,
@intCountPropertiesint,
@intCounterintcreate table #tmp_lock_who (
idintidentity(1,1),
spid smallint,
bl smallint)
IF @@ERROR<>0RETURN @@ERROR
insert into #tmp_lock_who(spid,bl) select0,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>0IF @@ERROR<>0RETURN @@ERROR--找到临时表的记录数
select @intCountProperties=Count(*),@intCounter=1from #tmp_lock_who
IF @@ERROR<>0RETURN @@ERRORif@intCountProperties=0select'现在没有阻塞和死锁信息'asmessage--循环开始while@intCounter<=@intCountProperties
begin--取第一条记录
select @spid=spid,@bl=bl
from #tmp_lock_who where Id=@intCounter
beginif@spid=0select'引起数据库死锁的是:'+CAST(@bl AS VARCHAR(10))+'进程号,其执行的SQL语法如下'elseselect'进程号SPID:'+CAST(@spid AS VARCHAR(10))+'被'+'进程号SPID:'+CAST(@bl AS VARCHAR(10))+'阻塞,其当前进程执行的SQL语法如下'DBCC INPUTBUFFER (@bl )
end--循环指针下移set@intCounter=@intCounter+1end
drop table #tmp_lock_whoreturn0end
需要的时候直接调用:
sp_who_lock
就可以查出引起死锁的进程和SQL语句.
SQL Server自带的系统存储过程sp_who和sp_lock也可以用来查找阻塞和死锁, 但没有这里介绍的方法好用。如果想知道其它tracenum参数的含义,请看www.sqlservercentral.com文章
我们还可以设置锁的超时时间(单位是毫秒), 来缩短死锁可能影响的时间范围:
例如:
use master
seelct @@lock_timeoutsetlock_timeout900000--15分钟
seelct @@lock_timeout