我有一个存储过程,用于查询繁忙的队列表,该表用于在我们的系统中分配工作。有问题的表在WorkID上具有主键,并且没有重复项。
该查询的简化版本是:
INSERT INTO #TempWorkIDs (WorkID)
SELECT
W.WorkID
FROM
dbo.WorkTable W
WHERE
(@bool_param = 0 AND
((W.InProgress = 0
AND ISNULL(W.UserID, -1) != @userid_param
AND (@bool_filtered = 0
OR W.TypeID IN (SELECT TypeID FROM #Types AS t)))
OR
(@bool_param = 1
AND W.InProgress = 1
AND W.UserID != @userid_param)
OR
(@Auto_Param = 0
AND W.UserID = @userid_param)))
OR
(@bool_param = 1 AND W.UserID = @userid_param)
OPTION
(RECOMPILE)
该#Types
表在该过程的前面填充。
如我所说,WorkTable
它很忙,有时在运行此查询时,我怀疑其中一条记录正从一组过滤器WHERE
移到另一组过滤器。具体来说,当某人开始处理某项并将其W.InProgress
从0更改为1时,就会发生这种情况。这种情况发生在我尝试向该查询要插入的临时表中添加主键时,出现重复键冲突。
我已确认在发生错误时生成的查询计划中没有并行性,隔离级别为READ COMMITTED
,并且源表中没有重复记录。您还可以看到这里没有JOIN
获得笛卡尔积的s或其他方法。
这是匿名查询计划:
问题是,是什么原因导致重复,我该如何停止?
我认为READ COMMITTED
应该在这里工作,我需要锁定。我几乎肯定,当InProgress
查询时记录中的位发生更改时,就会发生重复。我知道这是因为表存储了更改的时间,并且它在我查询并得到错误的毫秒之内。