1

次の表があります(大幅に簡略化されています):

Jobs: JobId, JobState
Data: DataId
JobsData: JobId, DataId

JobsData任意のアイテムDataを の 1 つまたは複数のアイテムに関連付けることができJobs、 の各アイテムに のJobs1 つまたは複数のアイテムをData関連付けることができます。

今、私は2つのトランザクションを持っています:

-- TRAN1
BEGIN TRAN
INSERT INTO Data VALUES (NewDataId)
INSERT INTO Jobs VALUES (NewJobId, StateInitial)
INSERT INTO JobsData VALUES (NewDataId, NewJobId)
UPDATE Jobs SET JobState=StateReady WHERE JobId=NewJobId
COMMIT TRAN

-- TRAN2
DECLARE @selectedId;
SELECT TOP (1) @selectedId=JobId FROM Jobs WITH (UPDLOCK, READPAST) WHERE JobState=StateReady
IF @selectedId IS NOT NULL
    SELECT DataId FROM JobsData WHERE JobId = @selectedId

ロックのヒントを含むコードは、この回答から来ています。その目的は、複数のTRAN2インスタンスを並行して実行し、決して同じものを取得しないようにすることJobIdです。

そのコードは SQL Server (既定の分離レベルREAD_COMMITTED) では正常に動作していますが、SQL Azure ではTRAN2正しく動作しないことがありSELECTます。これは、SQL Azure の既定の分離レベルが.JobIdSELECTREAD_COMMITTED_SNAPSHOT

問題を解決するために最小限の変更を行いたいのでTRAN2、最初に null を取得するかSELECT、2 番目に正しい結果セットを取得しますSELECT

どのテーブル ヒットをどの SQL ステートメントに適用するか?

4

1 に答える 1

0

まず、Azure でキューが必要な場合は、Azure Queues または Service Bus Queuesを使用します。

リレーションよりもキューを実装することに固執する場合は、Using Tables as Queuesのパターンを使用してください。具体的には:

  • イベント キューの代わりに状態フィールドを使用しないでください (「準備完了」はジョブ キュー内のレコードであり、イベントで あり、ジョブの状態ではありません)。
  • を使用してデキューDELETE ... WITH OUTPUT ...

これで私を信頼してください。

于 2013-01-10T12:43:42.817 に答える