数据库并发使用问题 - 在另一个用户已关闭的项目之后对表的更新

时间:2015-03-24 11:28:12

标签: 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              350
4   3              125

在上表中,如果ShippingList处于未完成状态,则可以更新ShippingList,即可以修改(甚至添加/删除)项目,直到其发货状态不完整为止。

如果多个用户同时打开了应用程序并且正在修改相同的ShippingList,则他们可以在本地具有不同的Shipping Items状态。如果第一个用户确认了ShippingList并将其移至COMPLETE状态,然后第二个用户尝试确认该股票,他最终会将更多的ShippingItem添加到已经关闭的ShippingList中。

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

我怎样才能实现这一目标?我使用的是MS SQL服务器。

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

2 个答案:

答案 0 :(得分:0)

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

听起来你想要使用乐观锁定模式。我建议您在要更新的表格上设置修改日期列。然后,数据的每个消费者将与数据一起获取该日期,并且当进行更新时,他们将日期重新传入。如果该行上的日期已经改变,则他们将尝试更新,你应该提出错误并中止而不是进行更新。

如果您正在寻找一个简单的解决方案,您可以在提交更改之前检查该行的状态。同样的交易,如果您的状态已经关闭,只需在进行更改前纾困。这可能会抓住99.9%的困境。

答案 1 :(得分:0)

注意:我对代码的访问权限有限,因此不得不将其推送到数据库级别,这也是多个程序实例同时运行和写入的正确位置。

使用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