gar*_*rik 11 sql-server-2008 deadlock
为什么这个查询会导致死锁?
UPDATE TOP(1) system_Queue SET
[StatusID] = 2,
@ID = InternalID
WHERE InternalID IN (
SELECT TOP 1
InternalID FROM system_Queue
WHERE IsOutGoing = @IsOutGoing AND StatusID = 1
ORDER BY MessageID ASC, InternalID ASC)
Run Code Online (Sandbox Code Playgroud)
添加死锁图:
<keylock hobtid="72057594236436480" dbid="9" objectname="Z.dbo.system_Queue" indexname="PK_system_Queue" id="lock5b25cc80" mode="X" associatedObjectId="72057594236436480">
<owner-list>
<owner id="processc6fe40" mode="X"/>
</owner-list>
<waiter-list>
<waiter id="processc7b8e8" mode="S" requestType="wait"/>
</waiter-list>
</keylock>
<keylock hobtid="72057594405453824" dbid="9" objectname="Z.dbo.system_Queue" indexname="IX_system_Queue_DirectionByStatus" id="lock48cf3180" mode="S" associatedObjectId="72057594405453824">
<owner-list>
<owner id="processc7b8e8" mode="S"/>
</owner-list>
<waiter-list>
<waiter id="processc6fe40" mode="X" requestType="wait"/>
</waiter-list>
</keylock>
Run Code Online (Sandbox Code Playgroud)
添加:
感谢Sankar的文章,其中提供了如何避免此类死锁的解决方案:
SQL*_*tar 13
在我看来,好像您试图在同一个语句中对同一个表执行 SELECT 和 UPDATE。
SELECT 在 IX_system_Queue_DirectionByStatus 索引中的值上持有共享锁,并且 UPDATE 需要释放这些锁,然后才能获得将更新主键的排他锁(我猜它是聚集的,也是IX_system_Queue_DirectionByStatus 键值)。
无论如何,我的猜测是这个查询只会在它选择和更新的索引值不冲突的极少数情况下成功。每次执行时是否都会死锁(我认为会)。
这是一个更详细地解释死锁的链接:http : //sqlblog.com/blogs/jonathan_kehayias/archive/2008/07/30/the-anatomy-of-a-deadlock.aspx
我不希望您将这篇文章标记为答案,而是希望其他 SQL Server 专家在此处分享有关此主题的更多信息。
归档时间: |
|
查看次数: |
8105 次 |
最近记录: |