2011-11-09 85 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