解決 SQL Server 訂單處理佇列中的競爭條件
挑戰:透過預存程序存取訂單佇列的並發訂單處理器會遇到競爭條件。這會導致重複訂單檢索和處理錯誤。 目前的預存程序嘗試透過一次鎖定 20 個訂單來緩解此問題,但這證明是不夠的。
有問題的查詢:
原始查詢使用帶有行鎖定的兩步驟流程(UPDATE 後面接著 SELECT),為競爭條件建立一個視窗:
<code class="language-sql">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</code>
根本原因: UPDATE 語句在 SELECT 語句辨識行之後嘗試鎖定行。 在多處理器環境中,這種時序差異允許多個處理器取得相同的訂單。
有效的解:在單一 語句中使用 READPAST
和 UPDLOCK
提示可以解決競爭條件。 UPDATE
允許 UPDATE 的 SELECT 部分繞過鎖定的行,而 READPAST
確保僅更新未鎖定的行。 UPDLOCK
修改後的查詢:
這種簡化的方法消除了競爭條件:
<code class="language-sql">UPDATE TOP (20) OrderTable SET ProcessorID = @PROCID FROM OrderTable WITH (ROWLOCK, READPAST, UPDLOCK) WHERE ProcessorID = 0</code>
以上是如何防止 SQL Server 訂單處理佇列中的競爭條件?的詳細內容。更多資訊請關注PHP中文網其他相關文章!