使用UPDLOCK,READPAST进行SQL队列处理并仍然遇到死锁

时间:2011-11-09 17:26:39

标签: sql-server sql-server-2005

以下存储过程就像冠军一样。这个存储过程有利于数千条记录的队列处理,并且经常同时触发(有时在任何给定时刻都可以连线7到8次):

Alter Procedure sp.QueueProcessSingle
As
DECLARE @aid int
update TABLE1 set [active] = 1, @aid = aid where aid=(
SELECT     TOP 1 aid
FROM         TABLE1 t1 WITH (UPDLOCK, READPAST)

WHERE
(t1.status is NULL) AND (t1.groupcount = 1) AND (t1.active = 0)
order by recorddate, recordtime)

update TABLE1 set status = 'Getting worked on' where @aid = aid

我对上述存储过程感到满意,但它是我不满意的第一个堂兄。类似的存储过程需要与上面的sp完全相同,只是它跨越一组记录。换句话说,不是仅仅将1条记录更新为"在其上执行工作,因此当存储过程再次执行时,不要再次获取此记录"它需要更新2或3或4个或更多具有相似数据(同名和电话)的记录。

我现在如何拥有这个私生子表兄弟并且我遇到了僵局:

Alter Procedure sp.QueueProcessMultiple
As
DECLARE @aid int
DECLARE @firstname nvarchar(50)
DECLARE @lastname nvarchar(50)
DECLARE @phone nvarchar(50)
update TABLE1 set active = 1, @aid = aid where aid=(
SELECT     TOP 1 aid
FROM         TABLE1 t1 WITH (UPDLOCK, READPAST)

WHERE
(t1.status is NULL) AND (t1.groupcount > 1) AND (t1.active = 0)
order by recorddate, recordtime)

UPDATE TABLE1 set status = 'Getting worked on' where @aid = aid

/****** Ok, now I have updated the "parent" record of the group which has the earliest date and time but now I also need to update the other records that are in this group*****/

SELECT @firstname = firstname, @lastname = @lastname, @phone = phone 
FROM TABLE1 WITH (UPDLOCK, READPAST)
WHERE @aid = aid

UPDATE TABLE1 set status = 'Getting worked on', active = 1 where @firstname = firstname AND @lastname = lastname AND @phone = phone AND status is NULL AND active = 0

正如通常的情况和stackoverflow之美的一部分,只需输入它就可以为我减轻一些亮光。似乎最好立刻更新整个组,而不仅仅是更新"父母"记录该组,然后更新表中具有父记录匹配数据的所有记录。现在怎么做?如果/当我得到它,我会继续寻找并发布解决方案,但任何输入都会非常感激。谢谢!

1 个答案:

答案 0 :(得分:2)

应该可以在一个声明中使用DENSE_RANK来获得急救 如果收集的行都具有相同的(recorddate,recordtime),则 此外,您还需要ROWLOCK

update
    t1
set
    set status = 'Getting worked on',
    active = 1,
    @aid = aid, @firstname = firstname, @lastname = lastname, @phone = phone 
FROM
    (
    SELECT
         DENSE_RANK() OVER (ORDER BY recorddate, recordtime) AS rn, 
         aid, firstname, lastname, status, active
    FROM TABLE1 t1x WITH (UPDLOCK, READPAST, ROWLOCK)
    WHERE
        (t1x.status is NULL) AND (t1x.groupcount > 1) AND (t1x.active = 0)
    ) t1;
WHERE
    rn = 1