0

我知道默认情况下 SQL 语句不会异步执行,但我遇到的情况似乎是这样的。

  • [#data]
  • [tbl_Bucket]
  • [tbl_IDPool]

程序

  • [sp_InsertIntoBucket]
  • [sp_GenerateID]
  • [sp_UpdateIDPool]

过程

  • 一个应用程序调用[sp_InsertIntoBucket]
  • [sp_InsertIntoBucket]来电[sp_GenerateID]
  • [sp_GenerateID]查询[tbl_IDPool]并生成一个值
  • [sp_GenerateID]来电[sp_UpdateIDPool]
  • [sp_UpdateIDPool]写信给[tbl_IDPool]
  • [sp_GenerateID]将其生成的值返回给[sp_InsertIntoBucket]
  • [sp_InsertIntoBucket]使用该值作为新记录的主键[tbl_Bucket]
  • [sp_InsertIntoBucket]将生成的值返回给调用者

设想

[#data]有信息(1500 - 12000 条记录)发往[tbl_Bucket]. 由于[sp_InsertIntoBucket]一次只能处理一条记录,因此该过程是 RBAR 的——因为每条记录都[#data] [sp_InsertIntoBucket]被调用。

问题

[sp_GenerateID]生成重复值。INSERT在实际发生[sp_InsertIntoBucket]并引发错误之前,我已经有 13 到 130 个重复生成的值。

生成的值取决于输入的数据,[tbl_IDPool]因此[sp_UpdateIDPool]为每次[sp_GenerateID]调用调用以确保下一次 [sp_GenerateID]调用生成唯一值也很重要。

我怀疑这与在完成写入[sp_GenerateID]之前被第二次调用有关。但这没有意义,因为 RBAR在移动到下一个条目之前应该等待哪个应该等待哪个应该等待,对吧?[sp_UpdateIDPool][tbl_IDPool][sp_InsertIntoBucket][sp_GenerateID][sp_UpdateIDPool][#data]

我试过的

  • WAITFOR DELAY "00:00:00.003"- 这行得通,但我正在寻找更好、更高效、更优雅的解决方案。
  • WHILEvs. CURSOR- 唯一的区别是CURSOR稍慢。
  • 在希望写入(第一次调用)会锁定读取(第二次调用)WITH (NOLOCK)[sp_GenerateID]查询中有和没有。[tbl_IDPool]
4

1 回答 1

0

[sp_GenerateID]尝试指定的开头

SET TRANSACTION ISOLATION LEVEL SERIALIZABLE

然后将剩余的内容包含在事务块中。

BEGIN TRANSACTION
...
COMMIT TRANSACTION
于 2014-10-02T09:31:09.270 回答