我有许多 .NET 进程从 SQL Server 2008 DB 表中读取消息并一次处理一个消息。我实现了一个简单的 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
但是,这是有缺陷的:有时一行会被“锁定”并处理两次。我怀疑存在并发问题:两个进程在更新状态之前先读取状态。
我认为这可以通过以某种方式实现读取 block 来解决(即使事务 block 读取),但我不确定如何做到这一点。有人可以帮忙吗?
提前非常感谢
瑞恩
最佳答案
为什么不直接替换整个东西
UPDATE t SET status = 'L' WHERE id = @id and status <> 'L'
RETURN @@ROWCOUNT
这将避免 2 次表访问和保持锁打开时间超过必要的时间。
关于.net - sp 执行时阻止读取行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3362769/