为什么此查询会导致死锁?
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)
添加了死锁图:
<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>
添加:
感谢Sankar的文章,其中提供了如何避免这种死锁的解决方案:
- 从读者的投影中消除不必要的列,因此他不必查找聚簇索引
- 将所需的列作为包含的列添加到非聚集索引中以使索引覆盖,从而使读者不必查找聚集索引
- 避免必须维护非聚集索引的更新
您使用哪个数据库平台的版本?默认的trx隔离(或并发)级别是多少?当前在system_Queue表上存在哪些索引?
—
SQLRockstar 2011年
添加了死锁图的@SQLRockstar部分,SQL Server 2008
—
garik 2011年
由IsOutGoing和StatusID提供的@SQLRockstar IX_system_Queue_DirectionByStatus索引。
—
garik 2011年