数据库发生死锁,怎么办??? 很奇怪的问题。

tongji_008 2015-01-04 12:49:15
存储过程A,自己锁自己。 存储过程B和存储过程C相互锁定。

问题如下截图所示:



问题一:存储过程为什么自己锁自己??? 是因为 “sp_who_lock”这个存储过程检查的不对吗???

问题二: 我该怎么样找到死锁发生的位置? 比如提示第333行。

但是存储过程的执行方式是, C过程调用 D过程,D过程调用 E过程 这种方式。 显示行号以后, 我应该从哪一行开始数???

从 Create proc语句,还是声明变量 declare ,还是 as begin ... 中间的隔开的行又算不算???
SQLServer提示的行号,应该怎么看???

求大神帮忙啊。

...全文
911 点赞 收藏 11
写回复
11 条回复
切换为时间正序
当前发帖距今超过3年,不再开放新的回复
发表回复
唐诗三百首 2015-02-16
sp_who_lock是第三方开发的存储过程,运行结果仅供参考. 建议启用1222跟踪标记,发生死锁后可查看SQL日志,有详细的死锁日志信息供分析.
回复
starrycheng 2015-01-27
引用 8 楼 DBA_Huangzj 的回复:
我一直对这个存储过程有点怀疑,最起码在2005以后应该用dmv来查死锁。或者直接看错误日志,2008以后甚至可以用扩充事件来实现。 另外,自己死锁是可能的,其中一个情景是存储过程进行了并行操作,进程之间发生了死锁。这个以前有个朋友问过我,结果他说优化一下脚本,让它不需要进行并行操作,就好了。
存储过程发生了并发。
回复
longerwull 2015-01-06
这个是并发导致的, 需要优化这个存储过程
回复
xiaoxiangqing 2015-01-05
把引起死锁的语句找出来
回复
yoan2014 2015-01-05
对于死锁的发生通常优化语句会带来不错的效果,找出存储过程中执行时间较长的语句优化看看
回复
發糞塗牆 2015-01-05
我一直对这个存储过程有点怀疑,最起码在2005以后应该用dmv来查死锁。或者直接看错误日志,2008以后甚至可以用扩充事件来实现。 另外,自己死锁是可能的,其中一个情景是存储过程进行了并行操作,进程之间发生了死锁。这个以前有个朋友问过我,结果他说优化一下脚本,让它不需要进行并行操作,就好了。
回复
florence31 2015-01-05


把所有的SELECT改成以下语法。。。

SELECT * FROM 表名 WITH (NOLOCK)

回复
starrycheng 2015-01-04
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
回复
江南小鱼 2015-01-04
你把存储过程以及相关的表结构贴出来
回复
注意,sp_who_lock 输出的是 死锁,而非阻塞,也就是说 你的存储过程 的2次执行, 比如:A 、B, 可能是 A阻塞了B,而同时B阻塞了A,所以A、B之间发生了死锁,才会导致上面的问题。 具体问题要具体分析,最好把代码贴出来
回复
卖水果的net 版主 2015-01-04
我看你发的这个图,都是同一个过程,阻塞了自己,应该不是问题。 也不存在死锁。 等你的过程执行一段时间,你再看看。 或者是,你这两个过程互相阻塞了,建议你查查你的这两个 usp 开头的过程。梳理一下执行流程。
回复
相关推荐
发帖
MS-SQL Server
创建于2007-09-28

3.3w+

社区成员

MS-SQL Server相关内容讨论专区
申请成为版主
帖子事件
创建了帖子
2015-01-04 12:49
社区公告
暂无公告