我一直使用类似于以下内容的方法来实现它:
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语句是原子性的。
有人有什么想法吗?
那“ JFDI”模式呢?
BEGIN TRY INSERT etc END TRY BEGIN CATCH IF ERROR_NUMBER() <> 2627 RAISERROR etc END CATCH
认真地说,这是最快且最并发的无锁操作,尤其是在大容量情况下。如果UPDLOCK升级并且整个表被锁定怎么办?