SQL Server的进程队列竞争状态
-
06-09-2019 - |
题
我具有由多个命令处理器通过存储过程访问的订单队列。每个处理器在通过一个唯一的ID,其用于锁定下一个20项目供自己使用。存储过程然后返回这些记录到订单处理器被作用。
有其中多个处理器能够获得相同的“OrderTable”记录此时它们试图同时在其上运行的情况。这最终导致在后面的过程中被抛出的错误。
我的下一步行动是允许每个处理器抓取所有可用的命令,只是循环赛的处理器,但我希望能简单地使代码线程安全的这一部分,并允许处理器抢只要他们喜欢的记录。
明确这样 - 任何想法,为什么我遇到这种竞争情况,我怎么能解决这个问题。
BEGIN TRAN
UPDATE OrderTable WITH ( ROWLOCK )
SET ProcessorID = @PROCID
WHERE OrderID IN ( SELECT TOP ( 20 )
OrderID
FROM OrderTable WITH ( ROWLOCK )
WHERE ProcessorID = 0)
COMMIT TRAN
SELECT OrderID, ProcessorID, etc...
FROM OrderTable
WHERE ProcessorID = @PROCID
解决方案
编辑:
我GOOGLE了检查我的回答:“处理数据队列与READPAST UPDLOCK和SQL Server的“。因为我了解并用此溶液发挥它已经多年。
原件:
如果您使用READPAST提示,然后锁定的行被跳过。你使用ROWLOCK所以你应该避免锁升级。您还需要UPDLOCK,因为我发现了。
所以过程1把锁20行,处理2将在未来20,处理需要3行41至60,等
在更新也可以写成这样:
UPDATE TOP (20)
foo
SET
ProcessorID = @PROCID
FROM
OrderTable foo WITH (ROWLOCK, READPAST, UPDLOCK)
WHERE
ProcessorID = 0
刷新,2011年10月
这可如果你需要一个SELECT和一气呵成的UPDATE做更多的优雅与OUTPUT子句。
其他提示
可以使用服务代理。你也可以使用sp_getapplock序列化到你的行访问 - 这将消除竞争条件:
“(在SQL Mutexs)通过创建自己的锁协助并发” http://sqlblogcasts.com/blogs/tonyrogerson/archive/2006 /06/30/855.aspx
不隶属于 StackOverflow