确保只有一个记录插入表中,并且有数千个并发用户

时间:2017-03-07 06:40:18

标签: sql sql-server sql-server-2014

最近,我需要编写一个存储过程,在第一个用户到来时只插入一条记录而忽略其他记录。我认为IF NOT EXISTS INSERT对我不起作用。此外,有些人在网上说MERGE增加了竞争条件。有没有快速实现这一目标的方法这是我现在的代码。

IF NOT EXISTS (SELECT ......)
INSERT

2 个答案:

答案 0 :(得分:0)

您可以添加另一个表以用作锁定机制。

我们假设您的表名为a,并且具有锁定值的表的名称为check_a

create table a (name varchar(10))
create table check_a (name varchar(10))

只将一条记录插入锁定表:

insert into check_a values ('lock')
go

然后创建一个存储过程,检查主表中是否有值。如果没有记录,我们可能会锁定表check_a中的唯一值,并将我们的值插入表a

create proc insert_if_first
as
begin
    set nocount on
    if not exists (select name from a)
    begin
        declare @name varchar(10)
        begin tran
        select @name = name from check_a with (updlock)
        if not exists (select name from a)
        begin
            insert into a values ('some value')
        end
        commit
    end
end

go

a中的第一个选择是检查没有记录是否尽可能低地使用系统资源。如果表a中有记录,我们可以跳过打开事务并跳过锁定行。

第二项检查是为了确保在我们等待获取锁定时,没有人在表a中插入一行。

这样,只有可以锁定check_a的第一个用户才能将值插入表a

答案 1 :(得分:0)

我猜你的意思是你希望用户创建一个存储过程,确保只有一个用户可以运行该过程。然后你需要使用隔离级别。有不同的隔离级别,因此您需要确定所需的隔离级别。

  • READ UNCOMMITTED
  • READ COMMITTED
  • REPEATABLE READ
  • SERIALIZABLE

你可以阅读他们在这里做的事情:

https://msdn.microsoft.com/en-us/library/ms173763.aspx