两个指数陷入僵局

时间:2014-09-04 09:29:24

标签: sql sql-server azure-sql-database deadlock

我在SQL Server(Azure SQL)中有一个表:

CREATE TABLE Commands
(
    Id int NOT NULL PRIMARY KEY,
    Body nvarchar(1000) NOT NULL,
    Priority int NOT NULL,
    DeliveryDate datetime NOT NULL,
    VisibleFrom datetime NULL,
)

该表还有一个索引:

CREATE NONCLUSTERED INDEX IX_PriorityAndDate ON Commands (Priority DESC, DeliveryDate ASC)

然后我有两个会话。

第1节

WITH command AS
(
    SELECT TOP(1) *
    FROM Commands q
    WHERE q.DeliveryDate <= @CurrentDate
      AND (q.VisibleFrom IS NULL OR q.VisibleFrom <= @CurrentDate)
    ORDER BY q.Priority DESC, q.DeliveryDate
)
UPDATE command SET command.VisibleFrom = DATEADD(SECOND, @LeaseTimeout, @CurrentDate)
OUTPUT inserted.Id,
       inserted.Body

第2节

DELETE FROM Commands WHERE Id = @Id

在某些情况下会发生死锁:

  1. 会话1锁定IX_PriorityAndDate索引(U锁定)。
  2. 会话2锁定PK_Commands索引(X锁定)。
  3. 会话1阻止等待PK_Commands(获取U锁)。
  4. 会话2阻止等待IX_PriorityAndDate(获取X锁定)。
  5. 如何解决此死锁?

1 个答案:

答案 0 :(得分:1)

在我看来,你有密钥查找死锁

尝试使用以下索引:

CREATE NONCLUSTERED INDEX IX_PriorityAndDate
  ON Commands (Priority DESC, DeliveryDate ASC) INCLUDE(VisibleFrom)

或尝试创建新索引:

CREATE NONCLUSTERED INDEX IX_PriorityAndDate
  ON Commands(DeliveryDate, VisibleFrom) INCLUDE(Priority)