次の方法で共有


キュー更新の競合の検出と解決

キュー更新サブスクリプションでは複数の場所で同じデータを変更できるため、パブリッシャーでデータが同期されるときに競合が発生する可能性があります。 レプリケーションは、変更がパブリッシャーと同期されたときに競合を検出し、パブリケーションの作成時に選択した解決ポリシーを使用してそれらの競合を解決します。 次の競合が発生する可能性があります。

  • 更新と挿入の競合。 この競合は、同じデータが 2 つの場所で変更されたときに発生します。 1 つの変更が勝ち、もう 1 つは負けます。

  • 競合を削除します。 この競合は、同じ行が一方の場所で削除され、もう一方の場所で変更されたときに発生します。

競合の検出と解決は、時間がかかり、リソースを集中的に消費するプロセスになる可能性があります。そのため、異なるサブスクライバーが異なるデータのサブセットを変更するようにデータ パーティションを作成することで、アプリケーションの競合を最小限に抑えるのが最善です。

競合の検出

パブリケーションを作成し、キュー更新を有効にすると、レプリケーションによって、既定値の newid() を持つ uniqueidentifier 列 (msrepl_tran_version) が基になるテーブルに追加されます。 パブリッシュされたデータがパブリッシャーまたはサブスクライバーで変更されると、行は新しい行バージョンが存在することを示す新しいグローバル一意識別子 (GUID) を受け取ります。 キュー リーダー エージェントは、同期中にこの列を使用して、競合が存在するかどうかを判断します。

キュー内のトランザクションでは、古い行バージョンと新しい行バージョンの値が保持されます。 パブリッシャーでトランザクションが適用されると、トランザクションからの GUID とパブリケーション内の GUID が比較されます。 トランザクションに格納されている古い GUID がパブリケーションの GUID と一致する場合、パブリケーションが更新され、サブスクライバーによって生成された新しい GUID が行に割り当てられます。 トランザクションの GUID を使用してパブリケーションを更新すると、パブリケーションとトランザクションで一致する行バージョンが作成されます。

トランザクションに格納されている古い GUID がパブリケーションの GUID と一致しない場合は、競合が検出されます。 サブスクライバーによって送信されるトランザクションに1つの行バージョンがあり、パブリッシャーに存在する新しい行バージョンがあるという2つの異なる行バージョンが存在することを、新しいパブリケーションのGUIDが示しています。 この場合、別のサブスクライバーまたはパブリッシャーは、このサブスクライバー トランザクションが同期される前にパブリケーション内の同じ行を更新しました。

マージ レプリケーションとは異なり、GUID 列の使用は行自体を識別するために使用されませんが、行が変更されたかどうかを確認するために使用されます。

競合の解決

キュー更新を使用してパブリケーションを作成する場合は、競合が検出された場合に使用する競合回避モジュールを選択します。 競合回避モジュールは、同期中に発生した同じ行の異なるバージョンをキュー リーダー エージェントが処理する方法を制御します。 パブリケーションのサブスクリプションがない限り、パブリケーションの作成後に競合解決ポリシーを変更できます。 競合回避モジュールの選択肢は次のとおりです。

  • パブリッシャーが優先される (既定値)

  • パブリッシャーが優先され、サブスクリプションが再初期化される

  • サブスクライバーが優先される

競合は記録され、競合ビューアーを使用して表示できます。

キュー更新競合解決ポリシーを設定するには

データの競合を表示するには

Publisher Wins

競合の解決がパブリッシャー優先に設定されている場合、トランザクションの整合性はパブリッシャーのデータに基づいて維持されます。 競合するトランザクションは、開始したサブスクライバーでロールバックされます。

キュー リーダー エージェントは競合を検出し、補正コマンドが生成され、ディストリビューション データベースにポストすることでサブスクライバーに伝達されます。 次に、ディストリビューション エージェントは、競合するトランザクションを発生させたサブスクライバーに補正コマンドを適用します。 補正アクションは、パブリッシャーの行と一致するようにサブスクライバーの行を更新します。

補正コマンドが適用されるまで、サブスクライバーで最終的にロールバックされるであろうトランザクションの結果を読み取ることが可能です。 これはダーティ リード (読み取りコミットされていない分離レベル) と同じです。 発生する可能性のある後続の依存トランザクションに対する補正はありません。 ただし、トランザクションの境界が尊重され、トランザクション内のすべてのアクションはコミットされるか、競合が発生した場合はロールバックされます。

パブリッシャーが優先され、サブスクリプションが再初期化される

競合を解決するためにサブスクライバーを再初期化すると、サブスクライバーでは厳密なトランザクション整合性が維持されますが、パブリケーションに大量のデータが含まれている場合は時間がかかる場合があります。

キュー リーダー エージェントが競合を検出すると、キュー内の残りのトランザクション (競合しているトランザクションを含む) はすべて拒否され、サブスクライバーは再初期化のマークが付けられます。 パブリケーションに対して生成された次のスナップショットは、ディストリビューション エージェントによってサブスクライバーに適用されます。

サブスクライバーの勝利

サブスクライバー優先ポリシーでの競合検出は、パブリッシャーを更新する最後のサブスクライバー トランザクションが優先することを意味します。 この場合、競合が検出されると、サブスクライバーによって送信されたトランザクションが引き続き使用され、パブリッシャーが更新されます。 このポリシーは、このような変更がデータの整合性を損なわないアプリケーションに適しています。

こちらもご覧ください

トランザクション レプリケーションの更新可能なサブスクリプション