hereのようなSQLテーブルを使用してキューシステムをセットアップする必要があります。ことで、この選択した後、私は、ので、私は私が最初の表においてROWLOCK
及び第二にUPDLOCK
を使用していORDER BYとWITH(ROWLOCK、UPDLOCK、READPAST)
BEGIN TRANSACTION
CREATE TABLE #Temp (ID INT, SOMEFIELD INT)
INSERT INTO #Temp SELECT TOP (@Something) TableA.ID, TableB.SomeField FROM TableA WITH (ROWLOCK, READPAST) INNER JOIN TableB WITH (UPDLOCK, READPAST) WHERE Condition1
INSERT INTO #Temp SELECT TOP (@Something) TableA.ID, TableB.SomeField FROM TableA WITH (ROWLOCK, READPAST) INNER JOIN TableB WITH (UPDLOCK, READPAST) WHERE Condition2
(...)
UPDATE TableB SET SomeField = 1 FROM TableB WITH (ROWLOCK, READPAST) WHERE ID IN (SELECT ID FROM #Temp)
COMMIT TRANSACTION
を使用しているストアドプロシージャ内、異なるcriteraによってキューに入れられたアイテムをフィルタリングする必要があるためTableB
のみ更新しますが、これらの行は他の並行クエリによってTableA
に更新されないようにする必要があります。上記のSELECT
のいずれかにORDER BY
句を挿入する必要があるまで、すべてがうまくいくので、非常に特定のIDだけが選択されます(私は本当にこれをしなければなりません)。何が起こるか:
1)ORDER BY
を指定しないと、2つの同時実行が必要に応じて実行され、異なる結果と重複しない結果が返されます。しかし、これらの正確な結果はすべてのSELECT
ステートメントの範囲外だったので、彼らは私が望む結果を返しません。
2)ORDER BY
と2回の同時実行を使用すると、最初の結果のみが結果を返します。 2番目のものは何も返しません。
WITH (ROWLOCK, READPAST)
とORDER BY
で動作するこれらの種類のクエリでは、注文に使用しているフィールドにインデックスを作成する必要があることを思い出してください。私はそれを試みたが、私は同じ結果を得た。どうすればこの問題を回避できますか?
編集:たとえば、私はフィールド(テストID INT、値INT)と値をテーブルTestTable
持っている場合は、 "(1,1)、(2,2)、..." と "同時" 実行
BEGIN TRANSACTION
SELECT TOP 2 TestID FROM TestTable WITH (UPDLOCK, READPAST)
WAITFOR DELAY '00:00:05'
COMMIT TRANSACTION
最初の実行は行(1,2)を返し、2番目の行は応答として(3,4)を返します。しかし、実行すると
BEGIN TRANSACTION
SELECT TOP 2 TestID FROM TestTable WITH (UPDLOCK, READPAST) ORDER BY VALUE ASC
WAITFOR DELAY '00:00:05'
COMMIT TRANSACTION
最初のものは(1,2)を返し、2番目のものは何も返しません。どうしてこれなの?!