【发布时间】:2015-07-06 12:57:10
【问题描述】:
我有一个名为Banners 的表,其中包含BID、impressions 等列...
另外,我创建了StoredProcedure,它在网页加载时执行。
存储过程
DECLARE @slot int
DECLARE @final varchar(MAX)
DECLARE @URL varchar(MAX)
DECLARE @ID varchar(MAX)
set @slot =0
SET @URL='';
SET @ID=0
SET @final='';
BEGIN
WHILE(@slot <= 6)
BEGIN
SET @slot= @slot+1
IF EXISTS(select BID from Banners (NOLOCK) where Slot=@slot AND SectionID =199 AND UserType in (@IsAnonymous,2) AND Enabled=1)
BEGIN
SET @final = (select TOP 1 '<div class=''sidebar-img''><a href ='''+ URL +''' id='''+CONVERT(varchar(10),BannerID)
+''' target=''_blank'' onclick=''Click(this)'';><img alt='''+Alt+''' src='''+BannerImage+''' height=''250'' width=''250''></a></div>'
FROM Banners (NOLOCK) where Slot=@slot AND Enabled=1 AND UserType in (@IsAnonymous,2)
AND SectionID =199
ORDER BY CHECKSUM(NEWID()))
IF(@final<>'')
BEGIN
SET @URL = @URL + @FINAL
SET @ID =(select replace( (select SUBSTRING(@final,charindex(' id=',@final)+5,4)),'''',''));
UPDATE Banners set impressions +=1 where BID=CONVERT(INT,@ID); <-- **this causes DEADLOCK**
END
ELSE
SET @URL = @final
END
ELSE
BEGIN
CONTINUE
END
END
SET @BannerHTML = @URL
END
主要是 deadlock issue 发生在 update statement 上,我们正在更新 Banners Table。
请告诉我任何阻止Deadlock 的建议。
【问题讨论】:
-
好吧,只有当两个进程在同一资源上并行运行时,才有可能发生死锁。您是否检查了哪两个进程发生冲突?您是否已经知道根本原因,现在尝试避免它?如果是这样,你能提供碰撞的查询吗?这会很有帮助。
-
@Ionic 我已经在 SP 中总结了......
-
是的,但你不能自己陷入僵局!锁是按会话设计的。如果您的过程在一个会话中运行,它本身就可以访问所有锁定的资源。这意味着您不能与自己的过程发生死锁。除了(未包含在您的文本中)您并行运行相同的过程(同时多次)。你呢?
-
当两个进程以不同的顺序访问相同的资源时,就会发生死锁。进程 A 持有资源 X 并追求资源 Y。进程 B 持有资源 Y 并追求资源 X。进程 A 和 B 永远等待对方“放手”他们想要的资源。 SQL Server 声明死锁。您需要使用死锁事件执行 SQL 跟踪/配置文件,并查看什么是死锁,以及 WHO。
-
@Ionic 是的,我试过了,在更新声明中说是死锁
标签: sql sql-server sql-server-2008 tsql deadlock