SQL トランスポートは、特定のロック ヒントを使用して行をロックし、競合する他のスレッドが現在ロックされている行を無視するようにします。
NServiceBus.SqlServer 2.2.0 (これを書いている時点での現在のバージョン) から、使用されているが、私が再フォーマットした SQL は次のとおりです。
WITH message AS
(
SELECT TOP(1) *
FROM [{Schema}].[{Queue}] WITH (UPDLOCK, READPAST, ROWLOCK)
ORDER BY [RowVersion] ASC
)
DELETE FROM message
OUTPUT deleted.Id, deleted.CorrelationId, deleted.ReplyToAddress,
deleted.Recoverable, deleted.Expires, deleted.Headers, deleted.Body;
共通テーブル式を使用してソース データを返す行を 1 つに制限し、次のロック ヒントを使用します。
UPDLOCK
- データを更新する目的でロック状態に保持する。
READPAST
- ロックされた行を無視し、次のロックされていない行をフェッチします。
ROWLOCK
- 行レベルのロックを強制し、ページ ロックやテーブル ロックにエスカレートしないでください。
全体を削除として実行し、削除しようとしているデータを出力することで、データを読み取ることができ、トランザクションがコミットされると、行が削除されます。それ以外の場合、トランザクションがロールバックすると、ロックが解放され、行は次の競合するコンシューマーによって取得されるのを待ちます。