次の方法で共有


ピア ツー ピア レプリケーションでの競合検出

ピア ツー ピア トランザクション レプリケーションを使用すると、トポロジ内の任意のノードでデータを挿入、更新、または削除し、データの変更を他のノードに反映できます。 任意のノードでデータを変更できるため、異なるノードでのデータの変更が互いに競合する可能性があります。 1 つの行が複数のノードで変更されると、その行が他のノードに反映されるときに競合が発生したり、更新が失われたりする可能性があります。

SQL Server 2008 以降のバージョンのピアツーピア レプリケーションでは、ピアツーピア トポロジ全体で競合検出を有効にするオプションが提供されます。 このオプションは、一貫性のないアプリケーションの動作や失われた更新プログラムなど、検出されない競合によって発生する問題を防ぐのに役立ちます。 このオプションを有効にすると、既定では競合する変更は、ディストリビューション エージェントの障害の原因となる重大なエラーとして扱われます。 競合が発生した場合、競合が解決され、トポロジ全体でデータの整合性が保たれるまで、トポロジは一貫性のない状態のままになります。

潜在的なデータの不整合を回避するには、競合検出が有効になっている場合でも、ピアツーピア トポロジでの競合を避けてください。 特定の行の書き込み操作が 1 つのノードでのみ実行されるようにするには、データにアクセスして変更するアプリケーションで、挿入、更新、および削除操作をパーティション分割する必要があります。 このパーティション分割により、あるノードで発生する特定の行に対する変更は、その行が別のノードによって変更される前に、トポロジ内の他のすべてのノードと同期されます。 アプリケーションで高度な競合検出および解決機能が必要な場合は、マージ レプリケーションを使用します。 詳細については、「マージ レプリケーション」および「 マージ レプリケーション競合の検出と解決」を参照してください

競合と競合検出について

1 つのデータベースで、異なるアプリケーションによって同じ行に加えられた変更によって競合が発生することはありません。 これは、トランザクションがシリアル化され、同時変更を処理するためにロックが使用されるためです。 ピアツーピア レプリケーションなどの非同期分散システムでは、トランザクションは各ノードで独立して動作します。複数のノード間でトランザクションをシリアル化するメカニズムはありません。 2 フェーズ コミットのようなプロトコルを使用できますが、これはパフォーマンスに大きく影響します。

ピア ツー ピア レプリケーションなどのシステムでは、個々のピアで変更がコミットされたときに競合が検出されません。 代わりに、それらの変更がレプリケートされ、他のピアで適用されるときに検出されます。 ピアツーピア レプリケーションでは、パブリッシュされた各テーブルの非表示列に基づいて、各ノードに変更を適用するストアド プロシージャによって競合が検出されます。 この非表示列には、各ノードに指定した 元の ID と行のバージョンを組み合わせた ID が格納されます。 同期中、ディストリビューション エージェントは各テーブルのプロシージャを実行します。 これらの手順では、他のピアからの挿入、更新、および削除操作が適用されます。 いずれかのプロシージャが非表示列の値を読み取るときに競合を検出すると、重大度レベルが 16 のエラー 22815 が発生します。

A conflict of type '%s' was detected at peer %d between peer %d (incoming), transaction id %s and peer %d (on disk), transaction id %s

既定では、このエラーにより、ディストリビューション エージェントはそのノードへの変更の適用を停止します。 検出された競合を処理する方法については、このトピックで後述する「競合の処理」を参照してください。

非表示の列には、専用管理者接続 (DAC) 経由でログインしているユーザーのみがアクセスできます。 DAC の詳細については、「 データベース管理者の診断接続」を参照してください。

ピア ツー ピア レプリケーションでは、次の種類の競合が検出されます。

  • インサート・インサート

    ピアツーピア レプリケーションに参加している各テーブルのすべての行は、主キー値を使用して一意に識別されます。 挿入競合は、同じキー値を持つ行が複数のノードに挿入された場合に発生します。

  • アップデート アップデート

    同じ行が複数のノードで更新されたときに発生します。

  • 挿入-更新

    あるノードで行が更新されたが、同じ行が削除され、別のノードに再挿入された場合に発生します。

  • 挿入・削除

    あるノードで行が削除されたが、同じ行が削除され、別のノードに再挿入された場合に発生します。

  • 更新-削除

    あるノードで行が更新されたが、同じ行が別のノードで削除された場合に発生します。

  • 削除-削除

    複数のノードで行が削除されたときに発生します。

競合検出の有効化

競合検出を使用するには、すべてのノードで SQL Server 2008 以降のバージョンが実行されている必要があります。すべてのノードに対して検出を有効にする必要があります。 SQL Server 2008 以降のバージョンでは、既定では、SQL Server Management Studio で競合検出が有効になっています。 競合が予想されないシナリオでも、検出を有効にすることをお勧めします。 競合検出は、Management Studio または Transact-SQL ストアド プロシージャを使用して有効または無効にすることができます。

  • Management Studio で検出を有効または無効にするには、[パブリケーションのプロパティ] ダイアログ ボックスの [サブスクリプション オプション] ページまたはピア ツー ピア トポロジの構成ウィザードの [トポロジの構成] ページを使用します。

    Management Studio を使用して競合検出を構成する場合、競合が検出されたときにディストリビューション エージェントが変更の適用を停止するように構成されます。

  • sp_addpublicationまたはsp_configure_peerconflictdetectionのストアド プロシージャを使用して、検出を有効または無効にすることもできます。

    ストアド プロシージャを使用して競合検出を構成する場合は、競合が検出されたときにディストリビューション エージェントが変更の適用を停止するかどうかを指定できます。 既定では、エージェントは停止します。 既定の設定を使用することをお勧めします。

競合の処理

ピア ツー ピア レプリケーションで競合が発生すると、ピアツーピアの競合検出アラートが発生します。 競合が発生したときに通知されるように、このアラートを構成することをお勧めします。 アラートの詳細については、「 レプリケーション エージェント イベントにアラートを使用する」を参照してください。

ディストリビューション エージェントが停止し、アラートが発生したら、次のいずれかの方法を使用して、発生した競合を処理します。

  • 必要なデータを含むノードのバックアップから競合が検出されたノードを再初期化します (推奨される方法)。 このメソッドは、データが一貫性のある状態であることを保証します。

  • ディストリビューション エージェントが引き続き変更を適用できるようにして、ノードを再度同期してみてください。

    1. sp_changepublication実行: @property パラメーターに 'p2p_continue_onconflict' を指定し、@value パラメーターにtrueを指定します。

    2. ディストリビューション エージェントを再起動します。

    3. 競合ビューアーを使用して検出された競合を確認し、関係する行、競合の種類、および勝者を特定します。 競合は、構成時に指定した発信元 ID 値に基づいて解決されます。最も高い ID を持つノードで発生した行が競合を優先します。 詳細については、「 トランザクション パブリケーションのデータ競合の表示 (SQL Server Management Studio)」を参照してください。

    4. 検証を実行して、競合する行が正しく収束していることを確認します。 詳細については、「 レプリケートされたデータの検証」を参照してください。

      この手順の後にデータに一貫性がない場合は、優先度が最も高いノードの行を手動で更新し、そのノードから変更を反映させる必要があります。 トポロジにそれ以上競合する変更がない場合、すべてのノードは一貫した状態になります。

    5. sp_changepublication実行: @property パラメーターに 'p2p_continue_onconflict' を指定し、@value パラメーターにfalseを指定します。

こちらもご覧ください

ピア ツー ピア トランザクション レプリケーション