【发布时间】:2011-03-25 09:14:39
【问题描述】:
我一直使用类似于以下的东西来实现它:
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)
不过,也许我使用了错误的锁或使用了太多的锁等。
我在 stackoverflow.com 上看到了其他问题,其中的答案建议使用“IF (SELECT COUNT(*) ... INSERT”等,但我一直处于(可能不正确)假设下,即单个 SQL 语句会是原子的。
有人有什么想法吗?
【问题讨论】:
-
您是否尝试过使用不带
WHEN MATCHED子句的合并? -
您使用的是什么版本的 SQL Server?
-
因客户而异。介于 2000 和 2008 R2 之间的任何内容。虽然我们可能在最初写声明时已经在 7 岁!
-
我必须看看这个新的(对我而言)
MERGE声明。在这种情况下它的表现会更好吗? -
我不明白这一点!只需插入您的数据,如果 PK 已经存在,则插入将失败,这很好。还是我错过了什么?
标签: sql sql-server tsql concurrency locking