在SQL Server存储过程中错误地使用HoldLock

时间:2013-11-11 21:31:09

标签: sql sql-server stored-procedures locks

我相信我错误地使用了HOLDLOCK

我认为这是因为我有一个像队列一样的表。队列从下面的SQL接收其项目,并在控制台应用程序中逐个处理。我尚未测试但我相信当这个控制台应用程序开始处理此表时,在一些长选择期间,下面的代码失败。为什么我认为...因为我在从表队列中抓取所有内容并在该控制台应用程序中逐个处理它时记录了GameID。有趣的是我认为没有通过的游戏没有在日志中创建它,因此我不相信它们被插入我的队列表中,我相信这是因为下面的HOLDLOCK

思想?

MERGE Test WITH (HOLDLOCK) AS GL
USING (SELECT @GameId AS ID) AS NewTest ON GL.ID = NewTest.ID
WHEN NOT MATCHED THEN
INSERT
(
    Id,
    FailedAttempts,
    DateCreated
)
VALUES
(
    NewTest.ID,
    0,
    SYSDATETIME()
);

1 个答案:

答案 0 :(得分:2)

我怀疑您的问题与您使用MERGEHOLDLOCK无关。我认为没有理由在这里引入繁琐的MERGE语法,因为它没有任何好处,especially given the potential issues it can cause in other areas。我建议一个非常简单的INSERT ... WHERE NOT EXISTS

INSERT dbo.Test(Id, FailedAttempts, DateCreated)
  SELECT @GameId, 0, SYSDATETIME()
  WHERE NOT EXISTS 
  (
    SELECT 1 FROM dbo.Test WITH (HOLDLOCK) 
    WHERE Id = @GameId
  );

由于herehere概述的原因,我宁愿盲目地尝试插入并获取PK违规 - 在几乎所有情况下,都迫使SQL Server尝试获取异常首先检查自己会产生更糟糕的表现。