我有一个使用事件编号(以及其他类型的编号)的应用程序。这些数字存储在名为“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 语句上吗?
如何确保不创建重复项?