我在 MS Sql Server 2008 R2 中有一个简单的队列实现。这是队列的本质:
CREATE TABLE ToBeProcessed
(
Id BIGINT IDENTITY(1,1) PRIMARY KEY NOT NULL,
[Priority] INT DEFAULT(100) NOT NULL,
IsBeingProcessed BIT default (0) NOT NULL,
SomeData nvarchar(MAX) NOT null
)
我想原子地选择按优先级排序的前 n 行以及 IsBeingProcessed 为 false 的 id 并更新这些行以说明它们正在被处理。我以为我会使用 Update、Top、Output 和 Order By 的组合,但不幸的是,您不能在 Update 语句中使用 top 和 order by。
因此,我创建了一个 in 子句来限制更新,并且该子查询按顺序执行(见下文)。我的问题是,这整个语句是原子的,还是我需要将它包装在事务中?
DECLARE @numberToProcess INT = 2
CREATE TABLE #IdsToProcess
(
Id BIGINT NOT null
)
UPDATE
ToBeProcessed
SET
ToBeProcessed.IsBeingProcessed = 1
OUTPUT
INSERTED.Id
INTO
#IdsToProcess
WHERE
ToBeProcessed.Id IN
(
SELECT TOP(@numberToProcess)
ToBeProcessed.Id
FROM
ToBeProcessed
WHERE
ToBeProcessed.IsBeingProcessed = 0
ORDER BY
ToBeProcessed.Id,
ToBeProcessed.Priority DESC)
SELECT
*
FROM
#IdsToProcess
DROP TABLE #IdsToProcess
这是一些用于插入一些虚拟行的 sql:
INSERT INTO ToBeProcessed (SomeData) VALUES (N'');
INSERT INTO ToBeProcessed (SomeData) VALUES (N'');
INSERT INTO ToBeProcessed (SomeData) VALUES (N'');
INSERT INTO ToBeProcessed (SomeData) VALUES (N'');
INSERT INTO ToBeProcessed (SomeData) VALUES (N'');