テーブルに挿入される行が 1 つだけであることを確認しようとしていますが、複数のプロセスが互いに衝突し、複数の行が取得されるという問題が発生しています。詳細は次のとおりです(おそらく必要以上に詳細です、申し訳ありません):
「エリア」の階層を保持する Areas というテーブルがあります。各「エリア」には、Orders テーブルに保留中の「注文」がある場合があります。階層化されているため、複数の「領域」を親の「領域」の下にグループ化できます。
FindNextOrder というストアド プロシージャがあります。このストアド プロシージャは、領域を指定すると、次の保留中の注文 (子領域にある可能性があります) を見つけて、それを「アクティブ化」します。「アクティブ化」とは、OrderID を QueueActive テーブルに挿入することを意味します。ビジネス ルールでは、エリアは一度に 1 つのアクティブな注文のみを持つことができます。
したがって、ストアド プロシージャには次のようなステートメントがあります。
IF EXISTS (SELECT 1 FROM QueueActive WHERE <Order exists for the given area>) RETURN
...
INSERT INTO QueueActive <Order data for the given area>
私の問題は、時々、2 つの異なるプロセスがこのストアド プロシージャをほぼ同時に呼び出すことです。それぞれが既存の行をチェックすると、それぞれにゼロが返されます。そのため、両方のプロセスが挿入ステートメントを実行し、1 つではなく 2 つのアクティブな注文が発生します。
これを防ぐにはどうすればよいですか?ああ、たまたま SQL Server 2012 Express を使用していますが、SQL Server 2000、2005、および 2008 でも機能するソリューションが必要です。
私はすでにテーブルを排他的にロックするための検索を行っており、この回答を見つけましたが、これを実装しようとして失敗しました。