【发布时间】:2011-09-01 12:36:25
【问题描述】:
互联网上有很多关于这个常见“问题”的信息。
解决方案如:
IF NOT EXISTS() BEGIN INSERT INTO (...) END
在我看来不是线程安全的,你可能会同意。
但是你能确认把exist放到一个单选的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)
【问题讨论】:
-
不,它在 readcommitted 或 uncommitted 级别都不起作用。您将需要一些额外的锁定提示。 Only inserting a row if it's not already there 的可能重复项
-
您不需要“帮助”exists 子句——它们足够聪明,可以在看到 1 行后完成。你可以只做
EXISTS (SELECT * FROM...,它会做正确的事。 -
它会做正确的事情,但在并发的情况下,它不够线程安全,并且在高负载下可能会发生主要违规错误。所以根据@Martin的链接,应该添加可重复读隔离事务。
-
@Paul - 我的意思是你不需要在 exists 子句中使用
select top 1...- 我没有评论代码的其余部分。 -
@Damien_The_Unbeliever Aaa 好的,很抱歉造成误解。我一直认为写:“top 1 1”不会使服务器获取列的值..
标签: sql-server transactions insert exists