我具有由多个命令处理器通过存储过程访问的订单队列。每个处理器在通过一个唯一的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

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top