2011-11-09 58 views
1

以下存储过程像冠军一样工作。这个存储过程有利于队列处理成千上万的记录,同时频繁触发(有时拧起来在任何给定时刻7或8次):使用UPDLOCK,READPAST处理SQL Queue并仍然出现死锁

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个或更多具有相似数据的记录(相同姓名和电话)。

以下是我有私生子表妹SP现在我越来越死锁:

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 

而且这是常有的情况和计算器的美的一部分,只是打字这件事是脱落了一点为我点亮它。似乎最好一次更新整个组,而不是更新组的“父”记录,然后更新表中具有父记录的匹配数据的所有记录。现在该怎么做?我会继续寻找,并会发布一个解决方案,如果/当我得到它,但任何输入将不胜感激。谢谢!

+0

不要在 “组” 的行具有相同的(recorddate,recordtime)? – gbn

回答

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 
+0

非常优雅,当然有用的想法。 – bwperrin