この記事では、Update ステートメントが DELETE/INSERT ペアとしてレプリケートされる可能性があることを説明します。
元の製品バージョン: SQL Server
元の KB 番号: 238254
まとめ
一意制約の一部である列が更新された場合、SQL Server は更新プログラムを "遅延更新" として実装します。これは、 DELETE
/INSERT
操作のペアとして意味します。 この "遅延更新" により、レプリケーションは DELETE
/INSERT
ステートメントのペアをサブスクライバーに送信します。 また、遅延更新の原因となる可能性があるその他の状況もあります。 そのため、サブスクライバーの UPDATE
トリガーまたはカスタム ストアド プロシージャに実装するビジネス ロジックも、 DELETE
/INSERT
トリガーまたはカスタム ストアド プロシージャに含める必要があります。
詳細
トランザクション レプリケーションの既定の動作では、 INSERT
、 UPDATE
、および DELETE
カスタム ストアド プロシージャを使用して、サブスクライバーに変更を適用します。
INSERT
パブリッシャーで行われたステートメントは、 INSERT
ストアド プロシージャ呼び出しを通じてサブスクライバーに適用されます。 同様に、 DELETE
ステートメントは、 DELETE
ストアド プロシージャ呼び出しを通じて適用されます。
ただし、 UPDATE
ステートメントが "遅延更新" として実行されると、ログ リーダー エージェントは、更新ストアド プロシージャ呼び出しではなく、ディストリビューション データベースに DELETE
/INSERT
ストアド プロシージャ呼び出しのペアをサブスクライバーに適用します。 たとえば、次の 3 つの列を含む、 TABLE1
という名前のパブリッシュ テーブルがあるとします。
- col1 int
- col2 int
- col3 varchar(30)
TABLE1
の唯一の一意制約は、主キー制約を使用してcol1
で定義されます。 1 つのレコード (1,1,'Dallas') があるとします。
このコードを実行する場合:
UPDATE TABLE1 set col1 = 3 where col3 = 'Dallas'
UPDATE
ステートメントは、一意のインデックスが定義されているcol1
を更新するため、SQL Server によって DELETE
/INSERT
ステートメントのペアとして実装されます。 したがって、ログ リーダーは、ディストリビューション データベースに DELETE
/INSERT
呼び出しのペアを配置します。 これは、サブスクライバーのトリガーまたはカスタム ストアド プロシージャに存在するすべてのビジネス ロジックに影響を与える可能性があります。 この状況を処理するには、追加のビジネス ロジックを DELETE
および INSERT
トリガーまたはストアド プロシージャに組み込む必要があります。
DELETE
またはINSERT
ペアではなく、単一行の更新をUPDATE
ステートメントとしてレプリケートする場合は、Trace フラグ 8207 を有効にすることができます。
さらに、パブリケーションで水平フィルターを使用し、更新された行がフィルター条件を満たしていない場合は、 DELETE
プロシージャ呼び出しのみがサブスクライバーに送信されます。 更新された行が以前にフィルター条件を満たしていなかったが、更新後の条件を満たしている場合は、 INSERT
プロシージャ呼び出しのみがレプリケーション プロセスを通じて送信されます。
前の例では、 TABLE1
: where col3 = 'Dallas'
で水平フィルターも定義されているとします。 このコードを実行する場合:
UPDATE table1 set col3 = 'New York' where col1 = 3
ログ リーダー エージェントは、更新された行が水平フィルター条件を満たしていないため、サブスクライバーに適用される DELETE
ストアド プロシージャ呼び出しのみを配置します。
ここで、このコードを実行する場合:
UPDATE table1 set col3 = 'Dallas' where col1 = 3
ログ リーダーは、行がフィルター条件を満たしていなかったため、 INSERT
ストアド プロシージャ呼び出しのみを生成します。
UPDATE
操作はパブリッシャーで実行されましたが、サブスクライバーでは適切なコマンドのみが適用されます。