Sql Server 2005 - 如果不存在则插入
互联网上有很多关于这个常见“问题”的信息。
在我看来,以下解决方案
IF NOT EXISTS() BEGIN INSERT INTO (...) END
不是线程安全的,您可能会同意。
但是你能确认将exists放入单选的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)
There is lots of information in the internet regarding this common "problem".
Solutions like:
IF NOT EXISTS() BEGIN INSERT INTO (...) END
are not thread-safe in my opinion and you will probably agree.
However could you confirm that putting the exist into the where clause of one single select would solve the problem of the highest concurrency in sql engine?
Is it enough?
insert into Table (columns)
select column1, column2, column3
where not exists (select top 1 1 from Table where something)
Should be there also added some higher transaction level or
can this be executed on a default one: committed?
Would this work under uncommitted level?
Thanks!
//Added later
Can i assume that both sql' are correct:
1)
set transaction isolation level repeatable read
IF NOT EXISTS() BEGIN INSERT INTO (...) END
2) set transaction isolation level repeatable read
insert into Table (columns)
select column1, column2, column3
where not exists (select top 1 1 from Table where something)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
使用 TRY/CATCH,您可以避免额外的读取
如果您可以丢弃重复项,这是一种高度可扩展的技术
链接:
With TRY/CATCH you can avoid the extra read
If you can discard duplicates, this is a highly scalable technique
Links:
要回答更新后的问题
可重复读取
仍然不够。您需要的是
holdlock
/serialized
级别。您正在尝试防止幻像(第一次读取时没有遇到行)条件,因此
NOT EXISTS
返回 true,但随后并发事务插入满足该条件的行)To answer the updated question
repeatable read
would still not be sufficient.It is
holdlock
/serializable
level that you would need.You are trying to prevent phantoms (where on the first read no rows met the criteria so the
NOT EXISTS
returns true but subsequently a concurrent transaction inserts a row meeting it)