使用锁定和有序输出更新数据库队列

时间:2015-01-28 20:20:49

标签: sql sql-server database

我有一个存在两个表(元数据和数据)的数据库队列。 storec proc锁定100行,更新行的状态并返回元+数据。我有一个执行存储过程的Windows服务。

存储过程

update top(100) QueueMeta WITH (UPDLOCK, READPAST)
SET Status = 'processing'
OUTPUT inserted.Id, 
        inserted.CreatedOn, 
        inserted.Timeout, 
        qd.Message,
        qd.Msisdn,
        inserted.NrOfRetries,
        inserted.MaxNrOfRetries             

FROM QueueMeta qm
INNER JOIN QueueData qd
    ON qm.Id = qd.QueueMetaId
WHERE Status = 'readytosend' and SendOn <= CURRENT_TIMESTAMP

问题是我需要在QueueMeta.Prio(int)上订购。我怎么办,因为订单不被允许?考虑#Temp但我需要相同的功能,因为我有两个不同的服务同时轮询数据库而不会失去性能。有什么建议吗?

/麦克

1 个答案:

答案 0 :(得分:2)

好吧,您可以使用表类型变量来选择具有排序功能。另请注意,必须在from子句中使用(UPDLOCK,READPAST)提示,以避免并发更新,如果发生这些更新,将会改变所选记录的状态。

DECLARE @Dequeued TABLE (
    Id BIGINT/INT PRIMARY KEY,
)

INSERT INTO @Dequeued
SELECT TOP (100)
    Id
FROM QueueMeta WITH (UPDLOCK, READPAST)
WHERE
    Status = 'readytosend' AND
    SendOn <= CURRENT_TIMESTAMP
ORDER BY Prio DESC

UPDATE qm
SET
    Status = 'processing'
OUTPUT
    INSERTED.Id, 
    INSERTED.CreatedOn, 
    INSERTED.Timeout, 
    qd.Message,
    qd.Msisdn,
    INSERTED.NrOfRetries,
    INSERTED.MaxNrOfRetries
FROM QueueMeta qm
INNER JOIN @Dequeued d
    ON d.Id = qm.Id
INNER JOIN QueueData qd
    ON qd.QueueMetaId = qm.Id

值得一提的是:如果尚未定义列Status,SendOn和Prio,请定义索引。