首页 > 解决方案 > 两个 (SELECT TOP 1 +1 ) 语句和两个 INSERTS 同时

问题描述

如果在执行事务时,另一台客户端计算机进行了插入,会发生什么情况?

我有两台客户端计算机和一个数据库。这些计算机上有相同的程序。假设我们有订单表和 salesorder# 列,该列是唯一的。

如果两台计算机同时执行,我知道 SQL 服务器将选择其中一个事务并让另一个等待。所以这个交易确实遵循

@ordernumber= SELECT TOP Salesorder# +1 .
 INSERT INTO order (salesorder#,dateship, user) VALUES (@ordernumber,GETDATE(),1,)

我相信如果两者同时发生,它只会选择 then 中的一个,完全运行,然后对另一个执行相同的操作。那是对的吗?

在不同的情况下会发生什么。如果事务开始,并且在 SELECT 语句之后但在 INSERT 发生之前请求另一个 INSERT(不是 TRANSACTION Just INSERT 语句)。

SQL Server 在这种情况下会做什么?这甚至可能吗?

标签: sql-serverdatabasetransactions

解决方案


一句话:不要这样做!!肯定会失败。

假设您有一个最大数量为 100 的表 - 现在您有两个(或多个)并发用户请求来执行插入。

两个请求都将首先读取最高数字 (100),然后每个请求都会将其递增 +1 - 因此两者内部的值都是 101。该SELECT语句只会做一个快速的共享锁——但两者都SELECT 可以工作,并且会读取 100 的值。它们是否在一个事务中在这里没有区别——仅仅因为有一个事务并不能阻止一秒钟SELECT的发生。

INSERT 实际上将创建一个排他锁 - 但仅在插入的行上(而不是整个表!)。阻止两个并发请求插入它们的新行并没有什么,并且两者都将尝试插入salesorder#值为 101 的行。如果您对此有唯一约束,则其中一个请求将失败,因为另一个请求已经插入了值为 101。

这是您不应该手动处理给出顺序 ID 的众多原因之一-让数据库通过使用INT IDENTITY列或SEQUENCE对象来处理它。


推荐阅读