Sql server 数据库并发使用问题-在其他用户已关闭项后更新表

Sql server 数据库并发使用问题-在其他用户已关闭项后更新表,sql-server,concurrency,Sql Server,Concurrency,这更多的是多个用户同时使用软件。考虑下面的表格 Table: ShippingList ID Status -- ------ 1 PENDING SUBMIT 2 COMPLETE 3 DRAFT Table: ShippingListItems ID ShippingListId Value -- -------------- ----- 1 1 100 2 1 110 3 2 3

这更多的是多个用户同时使用软件。考虑下面的表格

Table: ShippingList
ID  Status
--  ------
1   PENDING SUBMIT
2   COMPLETE
3   DRAFT

Table: ShippingListItems
ID  ShippingListId Value
--  -------------- -----
1   1              100
2   1              110
3   2              350
4   3              125
在上表中,如果ShippingList处于未完成状态,则可以对其进行更新,即可以修改(甚至添加/删除)项目,直到其装运状态为未完成

如果多个用户同时打开应用程序并修改同一ShippingList,则他们可以在本地拥有不同的装运项目状态。如果第一个用户确认ShippingList并将其移动到“完成”状态,然后第二个用户尝试确认库存,他将在已关闭的ShippingList上添加更多ShippingItems

这里需要在提交当前试图更新的股票已经关闭/完成之前,以某种方式检查用户2

我怎样才能做到这一点?我正在使用MS SQL server


编辑:如何在ShippingListItems表上写入触发器,以便在插入/更新时检查ShippingList的状态?

要正确执行此操作,需要实现并发模式。您选择哪一个取决于系统的使用方式

听起来您想要利用乐观锁定模式。我建议在要更新的表上设置一个修改日期列。然后,数据的每个使用者都会将该日期与数据一起获取,当进行更新时,他们会将该日期传递回。如果他们试图更新的行上的日期已更改,则应引发错误并中止,而不是进行更新


但是,如果您正在寻找一个简单的解决方案,您可以在提交更改之前检查该行的状态。同样的交易,如果你的状态已经结束,那么在做出改变之前,你可以先退出。这可能会抓住你99.9%的烦恼。

注意:我对代码的访问有限,因此必须将其向下推到DB级别,这也是同时运行和编写多个程序实例的正确位置

最后在ShippingListItem上使用触发器并在插入/更新时检查ShippingList的状态。这似乎解决了问题

CREATE TRIGGER [dbo].[ValidateShippingListItems]
   ON [dbo].[ShippingListItems]
   FOR INSERT, UPDATE
AS 
BEGIN
    if exists (select 1 from [dbo].[ShippingList] g inner join inserted i on i.ShippingList_Id = g.Id where g.Status = 3) 
    BEGIN
        RAISERROR ('Shipping List is already in COMPLETE status',16,1)
        ROLLBACK TRANSACTION
    END
END

您能发布所需的输出吗?@mohan111:required是用户2的提交应该失败,表示此发货列表已经完成。目前,它最终将从user-2的列表中添加装运项目到已完成的列表中。在尝试更新之前,应用程序至少应该检查装运列表的状态——如果已完成,请中止并通知用户。@dean:这对我来说是最理想的情况:)但不幸的是,系统组件是位分布式的,不完全可以检查它。这就是为什么我需要将此检查向下推到DB级别。可能是通过检查约束或其他方式,但不确定如何实现itOK,如果您使用的是存储过程,请在sp中执行检查。如果不是,请在ShippingListItems上编写一个instead of触发器,并在那里检查状态。