gpt4 book ai didi

sql-server - SQL Server SELECT/UPDATE 存储过程怪异

转载 作者:行者123 更新时间:2023-12-03 16:47:00 26 4
gpt4 key购买 nike

我有一个表用作工作队列。本质上,它由一个主键、一段数据和一个状态标志(已处理/未处理)组成。我有多个进程试图获取下一个未处理的行,因此我需要确保它们观察到正确的锁定和更新语义以避免竞争条件下流。为此,我定义了一个他们可以调用的存储过程:

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默认的。 "

http://msdn.microsoft.com/en-us/library/aa259216.aspx

我认为您在选择中没有得到任何东西,因为记录仍然被标记为脏。您必须更改事务隔离级别,或者,我所做的是先进行更新,然后读取记录,但是要执行此操作,您必须使用唯一值标记记录(我使用 getdate() 进行批处理但 GUID 将是您可能想要使用的)。

关于sql-server - SQL Server SELECT/UPDATE 存储过程怪异,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/562467/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com