我知道默认情况下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]
一次只能处理一条记录,因此该流程为RBAR&#ed; - 对于[sp_InsertIntoBucket]
[#data]
中的每条记录都会被调用。
问题
[sp_InsertIntoBucket]
生成重复值。在[sp_GenerateID]
中的实际INSERT
发生之前,我已经有13到130个重复生成的值,并且会抛出错误。
生成的值取决于[sp_InsertIntoBucket]
中的数据,因此为每个[tbl_IDPool]
调用调用[sp_UpdateIDPool]
以确保 next 也很重要[sp_GenerateID]
调用会生成唯一值。
我怀疑这与[sp_GenerateID]
在[sp_GenerateID]
写完[sp_UpdateIDPool]
之前第二次被调用有关。但这没有意义,因为RBAR应等待[tbl_IDPool]
等待[sp_InsertIntoBucket]
等待[sp_GenerateID]
,等待[sp_UpdateIDPool]
,然后再转到下一个[#data]
条目,正确?
我尝试了什么
WAITFOR DELAY "00:00:00.003"
- 这很有效,但我正在寻找更好,更有效,更优雅的解决方案。WHILE
与CURSOR
- 唯一的区别是CURSOR
略慢。WITH (NOLOCK)
[sp_GenerateID]
[tbl_IDPool]
查询中有{{1}}希望写入(第一次调用)会锁定读取(第二次调用)。答案 0 :(得分:0)
在[sp_GenerateID]
开头尝试指定
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE
然后将剩余内容包含在事务块中。
BEGIN TRANSACTION
...
COMMIT TRANSACTION