【发布时间】:2009-02-18 19:25:02
【问题描述】:
我有一张桌子用作工作队列。本质上,它由一个主键、一段数据和一个状态标志(已处理/未处理)组成。我有多个进程试图抓取下一个未处理的行,因此我需要确保它们观察到正确的锁定并更新语义以避免竞争条件恶劣。为此,我定义了一个他们可以调用的存储过程:
CREATE PROCEDURE get_from_q
AS
DECLARE @queueid INT;
BEGIN TRANSACTION TRAN1;
SELECT TOP 1
@queueid = id
FROM
MSG_Q WITH (updlock, readpast)
WHERE
MSG_Q.status=0;
SELECT TOP 1 *
FROM
MSG_Q
WHERE
MSG_Q.id=@queueid;
UPDATE MSG_Q
SET status=1
WHERE id=@queueid;
COMMIT TRANSACTION TRAN1;
注意使用“WITH (updlock, readpast)”来确保我锁定了目标行并忽略了已经被类似锁定的行。
现在,该过程如上所示,非常棒。然而,当我把它放在一起时,我发现如果第二个 SELECT 和 UPDATE 按顺序颠倒(即先 UPDATE 然后 SELECT),我根本没有得到任何数据。不,第二个 SELECT 是在最后的 COMMIT 之前还是之后都没有关系。
因此,我的问题是为什么第二个 SELECT 和 UPDATE 的顺序会有所不同。我怀疑那里发生了一些我不明白的微妙事情,我担心它以后会咬我。
有什么提示吗?
【问题讨论】:
标签: sql-server tsql stored-procedures