0

我相信我使用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()
);
4

1 回答 1

2

MERGE我怀疑您的问题与您使用or无关HOLDLOCK。我认为没有理由在这里引入繁琐的MERGE语法,因为它没有任何好处,尤其是考虑到它可能在其他领域引起的潜在问题。我建议一个非常简单的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
  );

由于此处此处概述的原因,我宁愿这样做而不是盲目地尝试插入并获取 PK 违规- 在几乎所有情况下,强制 SQL Server 尝试获取异常而不是首先检查自己会产生更差的性能。

于 2013-11-11T22:41:30.757 回答