SQL(Microsoft)-同时进行2次更新

SQL(Microsoft)-同时进行2次更新,sql,sql-server,Sql,Sql Server,我有一张桌子 create table lastnum ( id int, num int ) 它有一排 Id num 1 101 2个用户同时执行相同的存储过程-存储过程为 declare @num int set @num = (select num + 1 from lastnum where id = 1) update lastnum set num = @num where Id = 1 return @num 以精确微秒运行的命令的可能范围是什么?因

我有一张桌子

create table lastnum
(
 id int,
 num int
)
它有一排

Id    num

1     101
2个用户同时执行相同的存储过程-存储过程为

declare @num int

set @num = (select num + 1 from lastnum where id = 1)

update lastnum
set num = @num
where Id = 1

return @num

以精确微秒运行的命令的可能范围是什么?因此,即使在两次调用之后,num的值也只有102,我不确定它发生的“可能范围”是什么,但它肯定是可能的,这是因为在计算新值的行和更新值的行周围没有事务处理。

该代码肯定有可能“失败”,并向两个用户提供相同的数字

这是否真的可能在您的环境中发生取决于您的负载(如果此代码很少运行,您可能会侥幸逃脱)和服务器的配置方式。Sql Server具有不同的功能,可用于确定允许的潜在冲突程度。在最高隔离度下,该代码是完全安全的(假设您的用户得到一个隐式事务)。。。但性能损失可能会很严重

Sql Server具有内置机制,您应该使用这些机制来避免这些潜在冲突:即
identity
列和
scope\u identity()
函数。较新版本的Sql Server也有


或者显式事务也可以帮助您。。。但我会尽量避免使用这些选项,而选择这个答案中的其他选项。

输出子句可以满足您的需要

declare @t table (id int primary key, num int);
insert into @t values (1, 101);
declare @n table (num int);
update @t 
set num = num+1 
output inserted.num into @n
where id = 1;
select num from @n;

感谢Eric Brandt和Joel Coehoorn


解决方案是使用“序列”——我认为从SQL 2012开始的新功能是什么?任何人怎么可能知道这一点?阅读有关交易的文章。你是否希望有人告诉你“这种情况42%都会发生”?如果该计数很重要,则任何高于0%的值都是不可接受的。要回答海报,可能问题应该是“这会发生吗?”如果答案是肯定的,请建议如何进行。如果您使用的是SQL Server 2012或更高版本,这里您要查找的是SEQUENCE对象。还有
output
子句,它可以与
identity
列结合使用(如果海报环境中没有序列,这可能是一个更可行的选项)。