两个(SELECT TOP 1 +1)语句和两个INSERTS同时

时间:2019-03-10 04:39:37

标签: sql-server database transactions

如果在执行事务时,另一台客户端计算机插入了该怎么办?

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

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

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

我相信,如果两者都同时发生,那么它将只选择then中的一个,完全运行,然后对另一个进行相同的操作。正确吗?

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

在这种情况下,SQL Server将做什么?这有可能吗?

2 个答案:

答案 0 :(得分:1)

一个词: 不要这样做! 失败-可以肯定。

假设您有一个表,其最大数目为100-现在您有两个(或几个)并发用户请求来进行插入。

两个请求都将首先读取最高的数字(100),每个请求都将其增加+1-因此两个请求的内部值均为101。 SELECT语句仅会执行快速的共享锁-但两个SELECT 都将起作用,并且读取的值为100。无论是否“在交易内部没有任何区别-只是因为有交易不会停止第二秒钟SELECT发生。

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

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

答案 1 :(得分:0)

@marc_s谢谢您的帮助,我相信找到了一种遵循您的建议的方法(因为您非常了解您在说什么),同时以我想要的方式获得了销售数量。

我们的软件架构以网关为中心。因此,我们有客户端,向网关发送命令,然后网关与SQL SERVER通信。我将要做的是通过以不同的方式为客户端分配优先级,以防止网关在同一时间向同一表发送INSERT命令。

例如:如果我们有客户compuerta,我们称之为1,2,3。同时执行相同的操作。 (我知道从技术上讲不可能发生这种情况)我可以将优先级赋予1,然后一旦1完成,将执行2,然后执行3。我知道这不是SQL的解决方案,因为这样可以防止插入失败,并且可以保留salesorder#的IDENTITY。将失败插入发生的时间限制为几乎为0。

再次感谢您提供的所有帮助和解释,为什么不按照我以前想要的方式插入。建议阅读有关DB信息的书籍吗?