高度なマージ レプリケーションの競合 - 論理レコードでの解決

適用対象:SQL Server

ここでは、論理レコードの使用時に利用できる、競合検出および競合解決方法のさまざまな組み合わせを紹介します。 マージ レプリケーションでの競合は、複数のノードが同じデータを変更したとき、またはマージ レプリケーションが変更をレプリケートするときに制約違反などの特定の種類のエラーに遭遇したときに発生します。 競合の検出および解決の詳細については、「 Advanced Merge Replication Conflict Detection and Resolution」を参照してください。

アーティクルに対して競合の追跡と競合解決のレベルを指定するには、マージ レプリケーションのオプションの変更に関する記事を参照してください。

競合検出

論理レコードの競合検出方法は、 column_trackinglogical_record_level_conflict_detectionの 2 つのアーティクル プロパティによって決定されます。 SQL Server 2005 (9.x) 以降のバージョンでは、論理レコード レベルの検出もサポートしています。

logical_record_level_conflict_detection アーティクル プロパティは TRUE または FALSE のいずれかに設定できます。 この値はトップ レベルの親アーティクルに対してのみ設定してください。子アーティクルでは無視されます。 この値が FALSE の場合、マージ レプリケーションは以前のバージョンの SQL Server のように、アーティクルの column_tracking プロパティの値のみに基づいて、競合を検出します。 この値が TRUE の場合、マージ レプリケーションはアーティクルの column_tracking プロパティを無視し、論理レコードのどこかで変更が行われた場合に競合を検出します。 たとえば、次のシナリオについて考えてみます。

値を持つ 3 つのテーブルの論理レコード

CustomersOrders、または OrderItems テーブルの Customer2 論理レコードに対して 2 人のユーザーが値を変更した場合に競合が検出されます。 この例では、 UPDATE ステートメントを使用して行われた変更が含まれますが、競合は、 INSERT または DELETE ステートメントで行われた変更によっても検出できます。

競合解決

既定では、マージ レプリケーションは優先度に基づくロジックを使用して競合を解決します。 2 つのサブスクライバー データベースで競合する変更が行われた場合、サブスクリプションの優先度が高いサブスクライバー側の変更が優先されます。優先度が同じである場合は、パブリッシャーに先に到達した変更が優先されます。 行レベルおよび列レベルで検出する場合、競合に勝った行全体が常に競合に負けた行を上書きします。

logical_record_level_conflict_resolution アーティクル プロパティは TRUE または FALSE のどちらかに設定できます。 この値はトップ レベルの親アーティクルに対してのみ設定してください。子アーティクルでは無視されます。 この値が TRUE の場合、優先される論理レコード全体が優先度の低い論理レコードを上書きします。 FALSE の場合、優先される個々の行は、別のサブスクライバーまたはパブリッシャーからのものである可能性があります。 たとえば、Orders テーブルの行の競合ではサブスクライバー A が勝ち、関連する OrderItems テーブルの行の競合ではサブスクライバー B が勝つことがあります。 この結果、論理レコードの Orders 行はサブスクライバー A のものになり、 OrderItems 行はサブスクライバー B のものとなります。

競合解決と検出の設定の相関関係

競合の結果は、競合の検出および解決の設定の相関関係によって異なります。 次の例では、優先度に基づく競合解決法が使用されているものとします。 論理レコードを使用する場合、以下のケースが考えられます。

  • 行レベルまたは列レベルの検出、行レベルの解決

  • 列レベル検出、論理レコードの解決

  • 行レベルの検出、論理レコードの解決

  • 論理レコードの検出、論理レコードの解決

行レベルまたは列レベルの検出、行レベルの解決

この例では、パブリケーションは次のように構成されています。

  • column_tracking は TRUE または FALSE

  • logical_record_level_conflict_detection が FALSE

  • logical_record_level_conflict_resolution が FALSE

この場合、検出は行レベルまたは列レベルであり、解決は行レベルです。 これらは、論理レコードに対するすべての変更を 1 つの単位としてレプリケートさせる利点を活かしながら、論理レコード レベルでの競合の検出または解決を行わないように設定されています。

列レベルの検出、論理レコードの解決

この例では、パブリケーションは次のように構成されています。

  • column_tracking は TRUE です

  • logical_record_level_conflict_detection が FALSE

  • logical_record_level_conflict_resolution が TRUE

パブリッシャーとサブスクライバーは同じデータセットから開始され、論理レコードは orders テーブルと customers テーブル間で定義されています。 パブリッシャーは customers テーブルの custcol1 列および orders テーブルの ordercol1 列を変更します。 サブスクライバーは customers テーブルの同じ行の custcol1 および orders テーブルの同じ行の ordercol2 列を変更します。 customers テーブルの同じ列に対する変更で競合が発生しますが、 orders テーブルへの変更では競合は発生しません。

競合は論理レコード レベルで解決されるため、レプリケーション処理中に、パブリッシャーで行われた競合に勝った変更によって、サブスクライバー テーブルで行われた変更が置き換えられます。

関連する行に対する変更を示す 1 つ目の一連のテーブル。

行レベルの検出、論理レコードの解決

この例では、パブリケーションは次のように構成されています。

  • column_tracking は FALSE です

  • logical_record_level_conflict_detection が FALSE

  • logical_record_level_conflict_resolution が TRUE

パブリッシャーとサブスクライバーは同じデータセットから開始します。 パブリッシャーは customers テーブルの custcol1 列を変更します。 サブスクライバーは customers テーブルの custcol2 列および orders テーブルの ordercol2 列を変更します。 customers テーブルの同じ行に対する変更で競合が発生しますが、サブスクライバーの orders テーブルへの変更では競合は発生しません。

競合は論理レコード レベルで解決されるため、同期中にパブリッシャー側で行われた変更が優先され、サブスクライバー テーブルの変更を置換します。

関連する行に対する変更を示す 2 つ目の一連のテーブル。

論理レコードの検出、論理レコードの解決

この例では、パブリケーションは次のように構成されています。

  • logical_record_level_conflict_detection が TRUE

  • logical_record_level_conflict_resolution が TRUE

パブリッシャーとサブスクライバーは同じデータセットから開始します。 パブリッシャーは customers テーブルの custcol1 列を変更します。 サブスクライバーは orders テーブルの ordercol1 列を変更します。 同じ行または列に対する変更はありませんが、 custid=1 の同じ論理レコードが変更されているため、この変更は論理レコード レベルでは競合として検出されます。

競合は論理レコード レベルでも解決されるため、同期中は、パブリッシャーで行われた競合に勝った変更によって、サブスクライバー テーブルで行われた変更が置き換えられます。

関連する行に対する変更を示す 3 つ目の一連のテーブル。