解决订单处理中的 SQL Server 竞争条件
本文解决了一个常见问题:多个订单处理器在通过存储过程访问订单队列时遇到竞争条件。 该存储过程使用唯一的 ID 来锁定接下来的 20 个订单以进行处理。 然而,并发访问可能会导致多个处理器声明相同的顺序,从而导致处理错误。
根本原因是未提交事务的可见性。 即使使用通常会阻止同时行访问的 ROWLOCK
,未提交的更改对于检查锁的其他处理器来说也是不可见的。这会产生竞争条件。
解决方案涉及在 READPAST
和 UPDLOCK
语句中使用 SELECT
和 UPDATE
提示。 READPAST
告诉数据库绕过锁定的行,避免来自未提交更新的干扰。 UPDLOCK
确保更新行上的独占锁,直到事务提交,防止其他处理器修改它们。
这是包含这些提示的改进代码:
<code class="language-sql">BEGIN TRAN UPDATE TOP (20) foo SET ProcessorID = @PROCID FROM OrderTable foo WITH (ROWLOCK, READPAST, UPDLOCK) WHERE ProcessorID = 0 COMMIT TRAN SELECT OrderID, ProcessorID, etc... FROM OrderTable WHERE ProcessorID = @PROCID</code>
为了提高效率,请考虑使用 OUTPUT
子句。这合并了 SELECT
和 UPDATE
操作,一步更新表并返回修改的行。这消除了对单独 SELECT
语句的需要。
以上是如何解决订单处理队列中的 SQL Server 竞争条件?的详细内容。更多信息请关注PHP中文网其他相关文章!