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)
然而,这是有缺陷的:有时一行被"锁定"并处理两次.我怀疑存在并发问题:两个进程在更新之前读取状态.
我认为这可以通过某种方式实现一个读取块来解决(即使事务块读取),但我不确定如何做到这一点.有人可以帮忙吗?
非常感谢提前
瑞安
您是否尝试过使用:
SELECT @status = status FROM t (UPDLOCK) WHERE t.id = @id
Run Code Online (Sandbox Code Playgroud)
请参阅此链接了解更多详细信息。
您缺少的是SELECT语句通常不会锁定行,因此如果一个进程已执行SELECT但尚未执行UPDATE,但另一个进程出现并执行 SELECT,那么它将返回因为你还没有锁定它,所以请向后退。
通过使用UPDLOCK,您可以使用 SELECT 语句锁定该行,并防止其他进程取回该行,直到第一个进程提交事务(这是您想要的行为)。
编辑 当然,正如马丁建议的那样,用一条语句来完成它是最简单的方法,并且您根本不必处理锁定问题。
| 归档时间: |
|
| 查看次数: |
97 次 |
| 最近记录: |