UPDATE ステートメントは DELETE/INSERT ペアとしてレプリケートできます

この記事では、Update ステートメントが DELETE/INSERT ペアとしてレプリケートされる可能性があることを説明します。

元の製品バージョン: SQL Server
元の KB 番号: 238254

概要

一意の制約の一部である列が更新された場合、SQL Serverは更新を "遅延更新" として実装します。これは操作のDELETE/INSERTペアとして意味します。 この "遅延更新" により、レプリケーションはステートメントの DELETE/INSERT ペアをサブスクライバーに送信します。 また、遅延更新の原因となる可能性があるその他の状況もあります。 そのため、サブスクライバーのトリガーまたはカスタム ストアド プロシージャに UPDATE 実装するビジネス ロジックも、トリガーまたはカスタム ストアド プロシージャに DELETE/INSERT 含める必要があります。

詳細

トランザクション レプリケーションの既定の動作は、 と DELETE カスタム ストアド プロシージャを使用INSERTUPDATEしてサブスクライバーに変更を適用することです。

INSERT パブリッシャーで行われたステートメントは、ストアド プロシージャ呼び出しを通じてサブスクライバーに INSERT 適用されます。 同様に、 DELETE ステートメントはストアド プロシージャ呼び出しを DELETE 通じて適用されます。

ただし、 UPDATE ステートメントが "遅延更新" として実行されると、logreader エージェントはディストリビューション データベースにストアド プロシージャ呼び出しの DELETE/INSERT ペアを配置し、更新ストアド プロシージャ呼び出しではなくサブスクライバーに適用します。 たとえば、 という名前 TABLE1の発行テーブルがあり、次の 3 つの列があるとします。

  • col1 int
  • col2 int
  • col3 varchar(30)

TABLE1 唯一の一意制約は、主キー制約を使用して に col1 定義されます。 1 つのレコード (1,1,'ダラス') があるとします。

このコードを実行する場合:

UPDATE TABLE1 set col1 = 3 where col3 = 'Dallas'

ステートメントはUPDATE、一意のインデックスが定義されている を更新col1しているため、ステートメントのDELETE/INSERTペアとしてSQL Serverによって実装されます。 そのため、logreader はディストリビューション データベースに呼び出しの DELETE/INSERT ペアを配置します。 これは、サブスクライバーのトリガーまたはカスタム ストアド プロシージャに存在するすべてのビジネス ロジックに影響する可能性があります。 この状況を処理するには、追加の DELETE ビジネス ロジックを トリガー INSERT またはストアド プロシージャに組み込む必要があります。

1 つのロジックを使用する場合に、すべてのコマンドを UPDATE ペアとして DELETE/INSERT レプリケートする場合は、トレース フラグを有効にすることができます。

さらに、パブリケーションで水平フィルターを使用し、更新された行がフィルター条件を満たしていない場合は、プロシージャ呼び出しのみが DELETE サブスクライバーに送信されます。 以前に更新された行がフィルター条件を満たしていなかったが、更新後の条件を満たしている場合、プロシージャ呼び出しのみが INSERT レプリケーション プロセスを通じて送信されます。

前の例では、 に水平フィルターも定義TABLE1where col3 = 'Dallas'されているとします。 このコードを実行する場合:

UPDATE table1 set col3 = 'New York' where col1 = 3

logreader エージェントは、 DELETE 更新された行が水平フィルター条件を満たしていないため、サブスクライバーに適用されるストアド プロシージャ呼び出しのみを配置します。

次に、このコードを実行する場合:

UPDATE table1 set col3 = 'Dallas' where col1 = 3

行がフィルター条件を INSERT 満たしていなかったため、logreader はストアド プロシージャ呼び出しのみを生成します。

操作は UPDATE パブリッシャーで実行されましたが、サブスクライバーでは適切なコマンドのみが適用されます。