如果在执行事务时,另一台客户端计算机插入了该怎么办?
我有两台客户端计算机和一个数据库。这些计算机上具有相同的程序。假设我们有订单表和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将做什么?这有可能吗?
答案 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信息的书籍吗?