From:http://www.cnblogs.com/mzhanker/archive/2011/06/04/2072739.html
使用sqlserver作為數據庫的應用系統,都避免不了有時候會產生死鎖, 死鎖出現以后,維護人員或者開發人員大多只會通過sp_who來查找死鎖的進程,然后用sp_kill殺掉。利用sp_who_lock這個存儲過程,可以很方便的知道哪個進程出現了死鎖,出現死鎖的問題在哪里.
創建sp_who_lock存儲過程
CREATE
procedure
sp_who_lock
as
begin
declare
@spid
int
declare
@blk
int
declare
@
count
int
declare
@
index
int
declare
@lock tinyint
set
@lock=0
create
table
#temp_who_lock
(
id
int
identity(1,1),
spid
int
,
blk
int
)
if @@error<>0
return
@@error
insert
into
#temp_who_lock(spid,blk)
select
0 ,blocked
from
(
select
*
from
master..sysprocesses
where
blocked>0)a
where
not
exists(
select
*
from
master..sysprocesses
where
a.blocked =spid
and
blocked>0)
union
select
spid,blocked
from
master..sysprocesses
where
blocked>0
if @@error<>0
return
@@error
select
@
count
=
count
(*),@
index
=1
from
#temp_who_lock
if @@error<>0
return
@@error
if @
count
=0
begin
select
'沒有阻塞和死鎖信息'
return
0
end
while @
index
<=@
count
begin
if exists(
select
1
from
#temp_who_lock a
where
id>@
index
and
exists(
select
1
from
#temp_who_lock
where
id<=@
index
and
a.blk=spid))
begin
set
@lock=1
select
@spid=spid,@blk=blk
from
#temp_who_lock
where
id=@
index
select
'引起數據庫死鎖的是: '
+
CAST
(@spid
AS
VARCHAR
(10)) +
'進程號,其執行的SQL語法如下'
select
@spid, @blk
dbcc inputbuffer(@spid)
dbcc inputbuffer(@blk)
end
set
@
index
=@
index
+1
end
if @lock=0
begin
set
@
index
=1
while @
index
<=@
count
begin
select
@spid=spid,@blk=blk
from
#temp_who_lock
where
id=@
index
if @spid=0
select
'引起阻塞的是:'
+
cast
(@blk
as
varchar
(10))+
'進程號,其執行的SQL語法如下'
else
select
'進程號SPID:'
+
CAST
(@spid
AS
VARCHAR
(10))+
'被'
+
'進程號SPID:'
+
CAST
(@blk
AS
VARCHAR
(10)) +
'阻塞,其當前進程執行的SQL語法如下'
dbcc inputbuffer(@spid)
dbcc inputbuffer(@blk)
set
@
index
=@
index
+1
end
end
drop
table
#temp_who_lock
return
0
end
GO
|
在查詢分析器中執行:
exec sp_who_lock

直到最后的結果為:

