小编典典

仅在尚未插入的行插入

sql

我一直使用类似于以下内容的方法来实现它:

INSERT INTO TheTable
SELECT
    @primaryKey,
    @value1,
    @value2
WHERE
    NOT EXISTS
    (SELECT
        NULL
    FROM
        TheTable
    WHERE
        PrimaryKey = @primaryKey)

…但是一旦加载,就会发生主键冲突。这是唯一插入到该表中的唯一语句。那么这是否意味着上述陈述不是原子的?

问题在于,这几乎不可能随意重建。

也许我可以将其更改为以下内容:

INSERT INTO TheTable
WITH
    (HOLDLOCK,
    UPDLOCK,
    ROWLOCK)
SELECT
    @primaryKey,
    @value1,
    @value2
WHERE
    NOT EXISTS
    (SELECT
        NULL
    FROM
        TheTable
    WITH
        (HOLDLOCK,
        UPDLOCK,
        ROWLOCK)
    WHERE
        PrimaryKey = @primaryKey)

虽然,也许我使用了错误的锁,或者使用了过多的锁之类的东西。

看到了其他问题,那里的答案都提示“ IF(SELECT COUNT(*)…INSERT”等),但我始终处于(也许不正确)的假设,即单个SQL语句是原子性的。

有人有什么想法吗?


阅读 168

收藏
2021-05-05

共1个答案

小编典典

“ JFDI”模式呢?

BEGIN TRY
   INSERT etc
END TRY
BEGIN CATCH
    IF ERROR_NUMBER() <> 2627
      RAISERROR etc
END CATCH

认真地说,这是最快且最并发的无锁操作,尤其是在大容量情况下。如果UPDLOCK升级并且整个表被锁定怎么办?

2021-05-05