我有一个使用事件编号(以及其他类型的编号)的应用程序。这些数字存储在名为“Number_Setup”的表中,其中包含计数器的当前值。
当应用程序生成一个新事件时,它会在 number_setup 表中获取所需的数字计数器行(计数器可以每天、每周等重置并存储为 int)。然后它递增计数器并使用新值更新行。
该应用程序是多用户的(任何时候大约有 100 个用户,以及运行并获取 100 条事件记录并为每个请求事件编号的 sql 作业)。事件表有一些重复的事件编号,它们不应重复。
存储过程用于检索下一个计数器。
选择 @Counter = 计数器,@ShareId=share_id,@Id=id
FROM Number_Setup
WHERE LinkTo_ID=@LinkToId
AND Counter_Type='我'
IF isnull(@ShareId,0) > 0
开始
-- 使用父计数器
选择 @Counter = 计数器,@ID=id
FROM Number_Setup
哪里 ID=@ShareID
结尾
选择 @NewCounter = @Counter + 1
更新 Number_Setup 设置计数器 = @NewCounter
哪里 id=@Id
我现在已经用事务包围了那个块,但我不完全确定它会 100% 解决问题,因为我认为仍然存在共享锁,所以无论如何都可以读取计数器。
也许我可以在更新语句中检查计数器是否已更新
更新 Number_Setup 设置计数器 = @NewCounter
WHERE 计数器 = @Counter
如果@@ERROR = 0 并且@@ROWCOUNT > 0
提交交易
别的
回滚交易
我确信这是财务应用程序等中发票号码的常见问题。
我也无法将逻辑放入代码中并在该级别使用锁定。我也锁定在 HOLDLOCK 但我不确定它的应用程序。它应该放在两个 SELECT 语句上吗?
如何确保不创建重复项?