plsql 查询存储过程死锁语句_查询造成死锁的SQL语句

1、查询造成死锁的SQL语句

当SQL数据库的监控报警显示死锁进程数过多时,首先应该找出造成死锁的SQL语句是什么,打开“查询分析器”,将如下的存储过程输入到文本框中,检查语法,然后运行:

use master

go

CREATE PROCEDURE sp_who_lock AS

begin

declare @spid int,@bl int,

@intTransactionCountOnEntry int,

@intRowcount int,

@intCountProperties int,

@intCounter int

create table #tmp_lock_who(

id int identity(1,1),

spid smallint,

bl smallint)

if @@error<>0 return @@error

insert into #tmp_lock_who(spid,bl)

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

if @@error<>0 return @@error

--找到临时表的记录数

select @intCountProperties=count(*),@intCounter=1

from #tmp_lock_who

if @@error<>0 return @@error

if @intCountProperties=0

select '现在没有阻塞信息' as message

--循环开始

while

@intCounter<

运行完毕,输入exec sp_who_lock 执行存储过程,这时候就可以明确的找出哪个SQL语句造成的死锁和阻塞。

2、杀死锁和进程

我们找出了引起死锁的语句,那么如何去手动的杀死进程和锁?最简单的办法,重新启动服务。但是这里要介绍一个存储过程,通过显式的调用,可以杀死进程和锁。

use master

go

if exists (select * from dbo.sysobjects where id =

object_id(N'[dbo].[p_killspid]') and OBJECTPROPERTY(id, N'IsProcedure') = 1)

drop procedure [dbo].[p_killspid]

GO

create proc p_killspid

@dbname varchar(200)    --要关闭进程的数据库名

as

declare @sql  nvarchar(500)

declare @spid nvarchar(20)

declare #tb cursor for

select spid=cast(spid as

varchar(20)) from master..sysprocesses where dbid=db_id(@dbname)

open #tb

fetch next from #tb into @spid

while @@fetch_status=0

begin

exec('kill '+@spid)

fetch next from #tb into @spid

end

close #tb

deallocate #tb

go

--用法

exec p_killspid  'newdbpy'

3、查看锁信息

如何查看系统中所有锁的详细信息?在企业管理管理器中,我们可以看到一些进程和锁的信息,这里介绍另外一种方法。

--查看锁信息

create table #t(req_spid int,obj_name sysname)

declare @s nvarchar(4000)

,@rid int,@dbname sysname,@id

int,@objname sysname

declare tb cursor for

select distinct

req_spid,dbname=db_name(rsc_dbid),rsc_objid

from master..syslockinfo where

rsc_type in(4,5)

open tb

fetch next from tb into @rid,@dbname,@id

while @@fetch_status=0

begin

set @s='select @objname=name from

['+@dbname+']..sysobjects where id=@id'

exec sp_executesql @s,N'@objname

sysname out,@id int',@objname out,@id

insert into #t values(@rid,@objname)

fetch next from tb into

@rid,@dbname,@id

end

close tb

deallocate tb

select 进程id=a.req_spid

,数据库=db_name(rsc_dbid)

,类型=case

rsc_type when 1 then 'NULL 资源(未使用)'

when 2 then '数据库'

when 3 then '文件'

when 4 then '索引'

when 5 then '表'

when 6 then '页'

when 7 then '键'

when 8 then '扩展盘区'

when 9 then 'RID(行 ID)'

when 10 then '应用程序'

end

,对象id=rsc_objid

,对象名=b.obj_name

,rsc_indid

from master..syslockinfo a left join #t b on a.req_spid=b.req_spid

go

drop table #t

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值