SQL Server の注文処理キューの競合状態への対処
課題: ストアド プロシージャを介して注文キューにアクセスする同時注文プロセッサは、競合状態に遭遇します。これにより、注文の重複取得や処理エラーが発生します。 現在のストアド プロシージャは、一度に 20 個の注文をロックすることでこれを軽減しようとしていますが、これでは不十分であることがわかります。
問題のあるクエリ:
元のクエリでは、行ロックを伴う 2 段階のプロセス (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
ヒントを使用すると、競合状態が解決されます。 READPAST
では、UPDATE の SELECT 部分でロックされた行をバイパスできますが、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 中国語 Web サイトの他の関連記事を参照してください。