パブリッシャーとサブスクライバーのデータが一致しない

パブリッシャーとサブスクライバーのデータは、次の場合に未集約 (データが一致しない状態) と見なされます。

  • サブスクライバーとパブリッシャーにある行数が異なり、パブリケーションがフィルター選択されていない場合。パブリケーションがフィルター選択されている場合は、行数が異なることが予想されます。

  • 1 つ以上の行内のデータが、パブリッシャーとサブスクライバーで内容が異なる場合。

説明

パブリッシャーとサブスクライバーのデータは、さまざまな理由で未集約になる可能性があります。

  • サブスクライバーで読み取り専用であるべきデータが更新された場合。サブスクリプション データベースは、マージ レプリケーション、更新可能なサブスクリプションを使用したトランザクション レプリケーション、またはピア ツー ピア トランザクション レプリケーションを使用する場合を除き、読み取り専用として扱う必要があります。

  • サブスクライバーで、トリガーが使用された場合。トリガーによって、サブスクライバーにあるデータが変更されたり、ROLLBACK を発行した場合にそのデータが更新されない場合があります。

  • スクリプトが、サブスクライバーではレプリケーションによって実行され、パブリッシャーでは実行されない場合。

  • トランザクション パブリケーションに対するストアド プロシージャ実行のレプリケーションを行うと、サブスクライバーでは結果が異なる場合。

  • 制約の違反またはその他の問題点によって、サブスクライバーで行を挿入、更新、または削除できない場合。

ユーザーの操作

次の操作は、データが未集約かどうかを判別する方法、およびデータを集約する方法について説明しています。

  1. 検証を行うか、tablediff ユーティリティを使用して、データが未集約であるかどうかを判別します。

    • ディストリビューション エージェントまたはマージ エージェントを実行できる場合は、バイナリ チェックサム検証を実行して、データが不足しているかどうかを判別します。行数検証も使用できますが、この方法では、データの内容の違いは示されません。詳細については、「レプリケートされたデータの検証」を参照してください。

    • ディストリビューション エージェントまたはマージ エージェントを実行できない場合は、tablediff ユーティリティを実行して、データが未集約であるかどうかを判別します。レプリケートされたテーブルでこのユーティリティを使用する方法の詳細については、「レプリケートされたテーブルを比較して相違があるかどうかを確認する方法 (レプリケーション プログラミング)」を参照してください。

  2. データが未集約である場合、tablediff ユーティリティを使用して Transact-SQL スクリプトを生成し、データを集約させます。詳細については、「tablediff ユーティリティ」を参照してください。

データが未集約になる原因への対処

次の操作は、「説明」で示した原因への対処方法です。

  • サブスクライバーで、レプリケーション以外でデータが更新された場合。

    • ユーザーがサブスクライバーでデータを挿入、更新、および削除できるようにする場合は、マージ レプリケーション、更新可能なサブスクリプションを使用したトランザクション レプリケーション、またはピア ツー ピア トランザクション レプリケーションを使用します。詳細については、「マージ レプリケーションの概要」および「トランザクション レプリケーションで使用するパブリケーションの種類」を参照してください。

    • ユーザーがサブスクライバーでデータの挿入、更新、および削除を行えないようにする場合は、ROLLBACK という語を含み、NOT FOR REPLICATION オプション (レプリケーション エージェントが操作を実行するときにトリガーが起動されないようにするオプション) を使用する各テーブルに対して、トリガーを作成します。次に例を示します。

      USE AdventureWorks2008R2;
      GO
      CREATE TRIGGER prevent_user_dml
      ON Person.Address
      FOR INSERT, UPDATE, DELETE
      NOT FOR REPLICATION
      AS
      ROLLBACK;
      

      詳細については、「CREATE TRIGGER (Transact-SQL)」および「NOT FOR REPLICATION を使用した制約、ID、およびトリガの制御」を参照してください。

  • サブスクライバーで、トリガーが使用された場合。サブスクライバーでのトリガーは、未集約やその他の問題点の原因とならないように適切に管理する必要があります。

    • トリガーは、マージ レプリケーション、更新可能なサブスクリプションを使用したトランザクション レプリケーション、またはピア ツー ピア トランザクション レプリケーションを使用した場合にのみ、サブスクライバーでデータが変更されるようにする必要があります。詳細については、「マージ レプリケーションの概要」および「トランザクション レプリケーションで使用するパブリケーションの種類」を参照してください。

    • 多くの場合、トリガーは NOT FOR REPLICATION オプションを使用する必要があります。データを追跡テーブルに挿入するトリガーについて考えてみましょう。ユーザーが最初に行を挿入した場合、トリガーが起動され追跡テーブルに行が入力されるのは、適切な動作です。ただし、データがサブスクライバーにレプリケートされた場合は、不要な行が追跡テーブルに挿入されるのを防ぐために、トリガーが起動されないようにする必要があります。

      トリガーに ROLLBACK ステートメントが含まれており、そのトリガーが NOT FOR REPLICATION オプションを使用しない場合、サブスクライバーにレプリケートされた行は適用されない可能性があります。

    • トランザクション レプリケーションの場合、XACT_ABORT の設定、およびトリガー内での COMMIT および ROLLBACK ステートメントの使用に関する注意事項がさらにあります。詳細については、「トランザクション レプリケーションに関する注意点」の「トリガー」を参照してください。

  • スクリプトが、サブスクライバーではレプリケーションによって実行され、パブリッシャーでは実行されない場合。

    sp_addpublicationsp_addmergepublication@pre_snapshot_script パラメーターと @post_snapshot_script パラメーターを使用すると、スナップショットの適用前と適用後にスクリプトが実行されるように指定できます。詳細については、「スナップショット適用前および適用後のスクリプトの実行」を参照してください。ストアド プロシージャ sp_addscriptexec を使用すると、同期処理中に、スクリプトを実行できます。詳細については、「同期中にスクリプトを実行する方法 (レプリケーション Transact-SQL プログラミング)」を参照してください。

    これらのスクリプトは、通常、サブスクライバーでのログインの追加など、管理タスクに使用されます。スクリプトがサブスクライバーで読み取り専用として扱われるデータの更新に使用される場合、管理者は結果が未集約にならないことを確認する必要があります。

  • トランザクション パブリケーションに対するストアド プロシージャ実行のレプリケーションを行うと、サブスクライバーでは結果が異なる場合。

    ストアド プロシージャの実行をレプリケートする場合は、サブスクリプションを初期化したときに、プロシージャの定義がサブスクライバーにレプリケートされます。プロシージャがパブリッシャーで実行されると、レプリケーションは対応するプロシージャをサブスクライバーで実行します。詳細については、「トランザクション レプリケーションにおけるパブリッシング ストアド プロシージャの実行」を参照してください。

    ストアド プロシージャによって、サブスクライバーで異なる操作が実行された場合、またはパブリッシャーとは異なるデータが処理された場合、データの未集約が発生する可能性があります。計算を実行してから、この計算に基づいたデータを挿入するプロシージャの場合について考えます。サブスクライバーがフィルター選択され、サブスクライバーでの計算が別のデータに基づいている場合は、サブスクライバーに挿入される結果が異なったり、挿入が発生しない可能性があります。

  • 制約の違反、またはその他の問題点によって、サブスクライバーで行を挿入、更新、または削除できない場合。

    トランザクション レプリケーションの場合、制約違反はエラーとして扱われます。既定では、エラーが発生するとディストリビューション エージェントでの同期が停止されます (これらのエラーをスキップする方法については、「トランザクション レプリケーションでのエラーのスキップ」を参照してください)。マージ レプリケーションの場合、制約違反は競合として扱われます。競合はログに記録されますが、競合によってマージ エージェントでの同期が停止することはありません。どちらの種類のレプリケーションでも、あるノードで成功した挿入、更新、または削除が別のノードでは成功しない場合に、制約違反によってデータの未集約が発生する可能性があります。

    テーブルがパブリッシュされると、NOT FOR REPLICATION オプション セットを使用してサブスクリプション データベース内に外部キー制約と CHECK 制約を作成するように、既定のスキーマ オプションによって指定されます。制約に対して異なる設定がアプリケーションに必要な場合は、スキーマ オプションを変更します。詳細については、「スキーマ オプションを指定する方法 (SQL Server Management Studio)」および「スキーマ オプションを指定する方法 (レプリケーション Transact-SQL プログラミング)」を参照してください。