具有保证版本的SQL Server锁定表

时间:2017-09-15 15:08:35

标签: sql-server transactions locking

我有一个ASP.NET Web应用程序,它有一个关键点,用户可以为自己保留一些数字。

会发生什么:

  1. 有一个表格存储'last_box_number',即3044

  2. 应用程序读取此数字并使用它计算一些条形码,例如它需要接下来的100个数字,每个数字的编号从3045到3144.

  3. 应用程序将这些数字与数据库中的其他数据一起存储,并将“last_box_number”更新为3144.这是在事务中执行的。

  4. 问题是在1)和3)之间有可能另一个用户会做同样的事情并且会从未修改的表中读取3044,所以我需要用'last_box_number'来锁定表格,但如果是第一个用户失败(断开连接或发生其他任何不良事件)表将保持锁定状态。

    我对SQL Server锁定机制不是很熟悉,所以在一些超时后我需要保证锁定释放。

    无论如何,欢迎任何有关实施上述内容的最佳方法的建议。

    更新 好的,这是一个例子:

    CREATE TABLE [dbo].[sscc_numbers](
    [gs1prefix] [bigint] NOT NULL PRIMARY KEY,
    [rangestart] [int] NOT NULL,
    [lastnumber] [int] NOT NULL)
    
    CREATE TABLE [dbo].[ssccs](
    [id] [bigint] IDENTITY(1,1) NOT NULL,
    [sscc] [nvarchar](20) NOT NULL,
    [clientid] [nvarchar](50) NOT NULL,
    [referencenum] [int] NOT NULL,
    ... other fields
    

    user1想要预订10个号码(referencenum),因此他查询sscc_numbers表并获取'lastnumber',例如6。

    然后它开始它的业务并生成10个新的SSCC号码,参考号码从7到16(认为最后使用的号码是6)。完成后,他将这10个数字的相关数据插入sscc表中。然后他运行update sscc_numbers set lastnumber=16 ...

    现在我要避免的场景 - 假设第二个用户user2在user1忙时查询sscc_numbers并从sscc_numbers获得相同的数字6。然后,在user2完成后,他将无法将他的数据插入到ssccs表中,因为他使用了重复的引用号。

    另一方面,User1可能断开连接,处理数据的时间太长等等。如果我将sscc_numbers表锁定10-15秒这不会有问题,但在此之后,他需要重置他的工作和得到一个新的'lastnumber'

    如果事先知道新记录的数量会很好,但它可能会不时发生变化,这些参考数字是一致且独特的绝对必要。

1 个答案:

答案 0 :(得分:0)

有几种方法可以解决这个问题......我个人的偏好是使用与购物车类似的东西。用户加载他们的购物车(暂时保留一部分库存),然后签出,创建实际订单并减少实际库存......或放弃购物车将这些商品提供给其他购物者。

因此,我创建了一个表,只是为特定会话保留一个特定的框,并且在原始会话提交事务的最后一步(使其永久不可用)之前不允许任何其他会话使用它或者回滚以释放下一个用户的箱号。