sp执行时阻止读取行

Rya*_*yan 5 .net sql sql-server locking transactions

我有很多.NET进程从SQL Server 2008数据库表读取消息并一次处理一个.我实现了一个简单的SP来"锁定"任何一个进程正在读取的行,以避免任何两个进程处理同一行.

BEGIN TRAN

SELECT @status = status FROM t WHERE t.id = @id
IF @status = 'L'
BEGIN
    -- Already locked by another process. Skip this
    RETURN 0
END
ELSE
    UPDATE t SET status = 'L' WHERE id = @id
    RETURN 1
END

COMMIT
Run Code Online (Sandbox Code Playgroud)

然而,这是有缺陷的:有时一行被"锁定"并处理两次.我怀疑存在并发问题:两个进程在更新之前读取状态.

我认为这可以通过某种方式实现一个读取块来解决(即使事务块读取),但我不确定如何做到这一点.有人可以帮忙吗?

非常感谢提前

瑞安

dcp*_*dcp 2

您是否尝试过使用:

SELECT @status = status FROM t (UPDLOCK) WHERE t.id = @id
Run Code Online (Sandbox Code Playgroud)

请参阅链接了解更多详细信息。

您缺少的是SELECT语句通常不会锁定行,因此如果一个进程已执行SELECT但尚未执行UPDATE,但另一个进程出现并执行 SELECT,那么它将返回因为你还没有锁定它,所以请向后退。

通过使用UPDLOCK,您可以使用 SELECT 语句锁定该行,并防止其他进程取回该行,直到第一个进程提交事务(这是您想要的行为)。

编辑 当然,正如马丁建议的那样,用一条语句来完成它是最简单的方法,并且您根本不必处理锁定问题。