在互联网上有很多关于这个常见的“问题”的信息。
解决方案包括:
IF NOT EXISTS() BEGIN INSERT INTO (...) END
在我看来不是线程安全的,你可能会同意。
但是,您能否确认将exist放入单个select的where子句中就可以解决sql引擎中的最高并发问题?这足够了吗?
insert into Table (columns)
select column1, column2, column3
where not exists (select top 1 1 from Table where something)
是否还应该添加一些更高的事务级别,或者这是否可以在默认的事务级别上执行:已提交?
这会在未提交的级别下工作吗?
谢谢!
//稍后添加
我可以假设两个sql都是正确的吗:
1)设置事务隔离级别可重复读取
IF NOT EXISTS() BEGIN INSERT INTO (...) END
2)设置事务隔离级别可重复读取
insert into Table (columns)
select column1, column2, column3
where not exists (select top 1 1 from Table where something)
发布于 2011-05-25 15:41:39
使用TRY/CATCH可以避免额外的读取
BEGIN TRY
INSERT etc
END TRY
BEGIN CATCH
IF ERROR_NUMBER() <> 2627
RAISERROR etc
END CATCH
无论是在IF中还是在WHERE中,
如果您可以丢弃重复项,这是一种高度可伸缩的技术
链接:
在这里查看我的答案:Which is the best choice in delete-insert vs if-update else-insert?:
发布于 2011-05-25 15:53:19
要回答更新后的问题,repeatable read
仍然不够。
它是您需要的holdlock
/ serializable
级别。
您正在尝试阻止phantoms (在第一次读取时,没有满足条件的行,因此NOT EXISTS
返回true,但随后并发事务会插入满足条件的行)
https://stackoverflow.com/questions/6120819
复制相似问题