【发布时间】:2017-09-15 15:08:34
【问题描述】:
我有一个 ASP.NET Web 应用程序,它有一个关键点,用户可以为自己保留一些号码。
会发生什么:
有一个表存储'last_box_number',即3044
应用程序读取这个数字并用它计算一些条形码,例如它需要接下来的 100 个数字,每个数字从 3045 到 3144。
应用程序将这些数字与附加数据一起存储在数据库中,并将“last_box_number”更新为 3144。这是在事务中执行的。
问题在于,在 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
用户 1 想要预订 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 表中,因为他使用了重复的参考号。
另一方面,用户 1 可能会断开连接、处理数据时间过长等。如果我将 sscc_numbers 表锁定 10-15 秒,这不会有问题,但在那之后,他需要重置他的工作并获取一个新的“lastnumber”
如果事先知道新记录的数量会很好,但它会不时发生变化,这些参考编号必须一致且唯一。
【问题讨论】:
-
对我来说,似乎应该有一个完全不涉及锁定表的替代解决方案。但我无法完全理解您要求我回答的要求。如果您可以为表和虚拟数据添加一个带有一些架构的简单示例,我会更详细地查看。
-
一旦值被保留,它们可以被取消保留吗?如果发生这种情况,该范围会发生什么?它应该再次可用还是会被忽略,从而在您的箱号列表中留下空白?
-
如果我们排除了提供更多信息的更好解决方案的可能性,那么您很可能正在寻找应用程序锁 (mutexes)。本指南适用于 sql server 2005,但过程相同:Application Locks (or Mutexes) in SQL Server 2005 - Mladen Prajdić 和
sp_getapplock- docs -
不,这些数字不能是“未保留的”,但它们实际上只有在提供数据时才被保留,用户应该有 10-15 秒的时间来处理并返回信息,否则他应该重新开始。只有在插入信息后,“最后使用的号码”才应该真正更新。
标签: sql-server transactions locking