【发布时间】:2016-04-20 19:16:21
【问题描述】:
我有一张任务表。多个用户同时尝试完成一项任务。这个修剪后的查询是我逻辑的核心:
; WITH TASKS_CTE AS (
SELECT TOP(1) T.TASK_ID AS TASK_ID,
T.ASSIGNED_USER_CODE AS ASSIGNED_USER_CODE,
T.STATUS AS STATUS
FROM TASK T WITH (ROWLOCK,READPAST)
JOIN TASK_SCORE TS WITH (NOLOCK) ON TS.TASK_ID = T.TASK_ID
WHERE
T.STATUS = 0
ORDER BY TS.TOTAL_SCORE DESC
)
UPDATE TASKS_CTE
SET STATUS = 1,
ASSIGNED_USER_CODE = @USER_CODE,
OUTPUT INSERTED.TASK_ID, INSERTED.ASSIGNED_USER_CODE, INSERTED.STATUS INTO @NEXT_TASK_TABLE;
我省略了检查@@ROWCOUNT 以查看任务是否成功出列的部分。
事实证明(ROWLOCK, READPAST) 并没有阻止多个用户获得相同的任务。我在 SO 上遇到了这两个问题,在SQL Server Process Queue Race Condition 中建议指定(ROWLOCK, READPAST, UPDLOCK)。另一方面,建议在Using a database table as a queue (UPDLOCK, READPAST)。
因此我的问题是,除了(UPDLOCK, READPAST) 之外,我是否需要指定ROWLOCK 才能实现多客户端队列? (UPDLOCK, READPAST) 和 (UPDLOCK, READPAST, ROWLOCK) 之间到底有什么区别?
【问题讨论】:
标签: sql-server locking priority-queue race-condition