2009-03-04 6 views
2

Iは、これらの要件を有する複数のリーダーが同時に処理された作業項目のキューを含むデータベーステーブルを持っている:この複数のリーダーソリューションを有効にするための適切な分離レベルとは何ですか?

  • 各項目は一のリーダによって処理されるべきです。
  • 何らかの理由で読み取りが失敗した場合は、別のリーダーが処理するために、そのアイテムをキューに戻す必要があります。ここ

各リーダが次の操作を行うことになる、可能な解決策の擬似コードである:


1)キューから次の項目を読んで、どこかにローカルに格納します。

2)

3トランザクションを開始する)がそれを見てから、他の読者を防止するために、アイテムを削除します。削除が失敗した場合は、既に別のワーカーがアイテムを引っ張っていることを意味します。

4)(手順1でローカルに保存された)アイテムを処理します。これは長時間走っている可能性があります。

5)トランザクションをコミット:項目の削除がコミットされる、次の項目を

OR

6)ROLLBACKトランザクション(明示的なロールバックまたはリーダー障害)を処理するためにステップ1に行く:項目の削除はバック戻る圧延しますバック他のリーダ


のためにキューに私の質問は:私はステップ3(アイテムの削除)した後、他の読者がそれを見ることができないようにする必要があり、最低の分離レベルは何ですか?最低限、整合性を維持しながら並行性を最大限にしたいということです。

注それが重要な場合、私は、SQL Server 2005を使用していますが(私は、これは正しい、製品不可知論者であるべきだと思う?)一般的に

このアプローチ上の任意の他のフィードバックは大歓迎です。

答えて

1

私が使用した、これを処理するための別の方法は次のとおりです。

  1. 各作業項目は、国家とReaderIDのための別の列を持っています。州は 'N'ew、A'ctive、または' C'omplete 'にすることができます。 (私も 'E'エラーを使用します)

  2. 読者はそれぞれ独自のIDを持っています。

  3. リーダーの最初のアクションは、状態を 'A'に設定し、それ自体のReaderIDを設定する1つのSQL文を使用して、状態 'N'を持つ最初のキュー項目を更新することです。

  4. Readerは作業項目を処理し、終了すると状態を 'C'に設定します。

チェックアウト処理を1つのステートメントで実行することで、分離の問題を避けることができます。

SQLのようなものになります:キューID =は(キュー状態= 'N' FROM MIN(キューID)を選択)

UPDATEキュー
セット状態= 'A'、ReaderID = @myWorkerID

+0

これはREAD COMMITTED(デフォルト) –

+0

を使用していますが、この会話があったと思います。私はまだそれが欠陥ではないことを保持します。あなたはそれをテストしましたか?私が持っています。 – dkretz

+0

@le dorfier:私は今のところ投票しましたが、いくつかのSQLエキスパートと話し合い、あなたに戻ってきます... –

1

「キュー」メカニズムからアイテムを削除すると、それにアクセスすることはできません。実際にアイテムを処理している間は、トランザクションを開いたままにする必要はありません。

REPEATABLE READ分離レベル:

文は 変更されたデータが、まだ他のトランザクション であり、他のトランザクションが によって読み取られたデータを変更することはできないことをコミットしていない を読み取ることができないことを指定します現在の取引が現在の トランザクションが完了するまで

トランザクションでは、 トランザクションの各ステートメントで読み取られた共有ロックは、 トランザクションが完了するまで保持されます。これにより、 他のトランザクションは、 現在のトランザクションによって読み取られた 行を変更できなくなります。 トランザクションは、 トランザクションによって発行された ステートメントの検索条件と一致する新しい行を、 に挿入できます。現在の トランザクションが文 を再試行すると、 はファントム読み取りの結果となる新しい行を取得します。 共有ロックは、各ステートメントの最後に を解放するのではなく、 トランザクションの最後に保持されるため、 の同時実行性はデフォルトの READ COMMITTED分離レベルよりも低くなります。このオプションは、必要な場合にのみ を使用してください。

+0

何らかの理由で読者が失敗した場合に備えて、トランザクションを開いたままにしておきます。この場合、削除を取り消して別の読者が処理できるようにします。 – DSO

+0

コミット読み取りが機能しないのはなぜですか?あなたが送信したそのMSDNリンクは、読み込みコミットでは、変更されたが他のトランザクションによってコミットされていないデータは読み込みできません。これは、読者がトランザクション内で削除を実行したときに他の読者がそれを読むことができないということを意味しないのでしょうか? – DSO

0

クエリでローレベルロックとreadpastステートメントを使用する場合は、ロックされていない行だけを選択できます。

このようになります。キューから

SELECTキュー (ROWLOCK、XLOCK、READPAST)WHERE状態= 'N'

私はあなたが大幅にお手伝いをいたしますSQLサーバーでのヒントをロック上に読むことをお勧めします。

+0

残念ながら、多くの人にとって、あなたを混乱させるようです。 – dkretz

関連する問題