トランザクション レプリケーションの更新可能なサブスクリプション

注意

この機能は、将来のバージョンの Microsoft SQL Server では削除される予定です。新しい開発作業では、この機能の使用を避け、現在この機能を使用しているアプリケーションは修正するようにしてください。

トランザクション レプリケーションでは、更新可能なサブスクリプションおよびピア ツー ピア レプリケーションによるサブスクライバでの更新をサポートしています。2 種類の更新可能なサブスクリプションを以下に示します。

  • 即時更新。サブスクライバのデータを更新するために、パブリッシャとサブスクライバを接続する必要があります。

  • キュー更新。サブスクライバのデータを更新するために、パブリッシャとサブスクライバを接続する必要はありません。サブスクライバまたはパブリッシャがオフラインでも更新できます。

サブスクライバでデータが更新されると、更新はまずパブリッシャに反映され、次に他のサブスクライバに反映されます。即時更新を使用した場合、変更は 2 フェーズ コミット プロトコルを使用して即時に反映されます。キュー更新を使用した場合、変更はキューに格納されます。キューに登録されたトランザクションは、ネットワーク接続が可能であればいつでも、パブリッシャで非同期に適用されます。更新は非同期的にパブリッシャに反映されるので、同じデータがそのパブリッシャまたは別のサブスクライバによって更新済みになると、更新の適用時に競合が生じる可能性があります。競合の解決方法はパブリケーションの作成時に設定され、この方法に従って競合が検出されて解決されます。

パブリケーションの新規作成ウィザードで更新可能なサブスクリプションによるトランザクション パブリケーションを作成する場合は、即時更新およびキュー更新の両方が有効になります。ストアド プロシージャによるパブリケーションを作成する場合は、どちらか一方または両方のオプションを有効にすることができます。パブリケーションに対してサブスクリプションを作成する場合は、使用する更新モードを指定します。必要に応じて、更新モードを切り替えることができます。詳細については、以下の「更新モードの切り替え」を参照してください。

トランザクション パブリケーションの更新可能なサブスクリプションを有効にするには

トランザクション パブリケーションの更新可能なサブスクリプションを作成するには

更新モードの切り替え

更新可能なサブスクリプションを使用する場合に、サブスクリプションに 1 つの更新モードを指定し、アプリケーションで別の更新モードが必要な場合はそちらに切り替えるように指定できます。たとえば、サブスクリプションで即時更新を使用するが、システム障害でネットワークに接続できなくなった場合には、キュー更新に切り替えるように指定することができます。

注意

レプリケーションでは、自動的に更新モードの切り替えを行いません。SQL Server Management Studio により、更新モードを設定するか、アプリケーションから sp_setreplfailovermode (Transact-SQL) を呼び出してモードを切り替える必要があります。

即時更新からキュー更新へ切り替えた場合、サブスクライバとパブリッシャが接続され、キュー リーダー エージェントがキューにあるすべての保留メッセージをパブリッシャに適用するまで、即時更新に戻すことはできません。

更新モードを切り替えるには

更新モードを切り替えるには、両方の更新モードに対してパブリケーションとサブスクリプションを有効にしてから、必要に応じてこれらを切り替える必要があります。

更新可能なサブスクリプションの使用に関する注意点

全般的な注意点

  • 更新サブスクリプションは、Microsoft SQL Server 2000 SP3 以降のバージョンを実行するサブスクライバでサポートされています。

  • 更新サブスクリプションまたはキュー更新サブスクリプションに対してパブリケーションを有効にすると、このオプションをパブリケーションに対して無効にできません (サブスクリプションで使用する必要がない場合でも同様)。このオプションを無効にするには、パブリケーションを削除し、新しいパブリケーションを作成する必要があります。

  • データの再パブリッシュはサポートされていません。

  • レプリケーションでは、追跡のため、パブリッシュされたテーブルに msrepl_tran_version 列を追加します。追加したこの列により、すべての INSERT ステートメントには、列リストを含める必要があります。

  • 更新サブスクリプションをサポートするパブリケーションのテーブルでスキーマ変更を行うには、パブリッシャおよびサブスクライバでのテーブルの利用をすべて停止し、スキーマ変更を行う前に、保留中のデータの変更をすべてのノードに反映させる必要があります。これにより、未完了のトランザクションが保留中のスキーマ変更と競合しません。スキーマ変更がすべてのノードに反映されたら、パブリッシュされたテーブルの操作を再開できます。詳細については、「レプリケーション トポロジを停止する方法 (レプリケーション Transact-SQL プログラミング)」を参照してください。

  • 更新モードを切り替える場合、サブスクリプションが初期化された後で、少なくとも 1 回はキュー リーダー エージェントを実行する必要があります (既定では、キュー リーダー エージェントは連続的に実行されます)。

  • サブスクライバ データベースが行方向にパーティション分割され、そのパーティションにパブリッシャではなくサブスクライバの行が入る場合は、サブスクライバはそれ以前に存在した行を更新することはできません。これらの行を更新しようとすると、エラーが返されます。行はテーブルから削除され、パブリッシャで追加されます。

サブスクライバでの更新

  • サブスクライバでの更新は、サブスクリプションの有効期限が切れていたり、アクティブでない場合でも、パブリッシャに反映されます。そのようなサブスクリプションは、削除または再初期化してください。

  • TIMESTAMP 列または IDENTITY 列が使用され、これらの列が基本データ型としてレプリケートされる場合、列の値はサブスクライバでは更新されません。

  • textntextimage 値は、レプリケーションの変更の追跡トリガ内で挿入または削除されたテーブルから読み取ることができないため、サブスクライバはこれらを更新または挿入できません。同様に、WRITETEXT や UPDATETEXT を使用すると、text 値や image 値を更新したり挿入したりすることができません。これらのデータはパブリッシャによって上書きされるからです。ただし、text 列と image 列を別々のテーブルに分けて、トランザクション内で 2 つのテーブルを変更することはできます。

    サブスクライバでラージ オブジェクトを更新するには、textntextimage のデータ型の代わりに、それぞれ、varchar(max)nvarchar(max)varbinary(max) のデータ型を使用します。

  • 一意なキー (主キーを含む) に対する更新によって重複が生じる場合 (たとえば、UPDATE <column> SET <column> =<column>+1 などの形式による更新)、その更新を行うことはできません。その更新は一意性違反のため拒否されます。これは、サブスクライバで行われた SET 更新が、レプリケーションによって、影響される各行に対する個々の UPDATE ステートメントとして反映されるからです。

  • サブスクライバ データベースが行方向にパーティション分割されていて、行を含むパーティションがサブスクライバにはあっても、パブリッシャにはない場合、この既存の行をサブスクライバは更新できません。これらの行を更新しようとすると、エラーが返されます。この行は、テーブルから削除し、再び挿入する必要があります。

ユーザー定義トリガ

  • サブスクライバでアプリケーションがトリガを必要とする場合、パブリッシャおよびサブスクライバで NOT FOR REPLICATION オプションを使用してトリガを定義する必要があります。このオプションの詳細については、「NOT FOR REPLICATION を使用した制約、ID、およびトリガの制御」を参照してください。これにより、トリガは元のデータの変更に対してのみ起動され、その変更がレプリケートされるときには起動されません。

  • ユーザー定義トリガは、レプリケーション トリガがテーブルを更新するときには起動されません。これは、ユーザー定義トリガの本文で、プロシージャ sp_check_for_sync_trigger を呼び出すことにより実現されます。詳細については、「sp_check_for_sync_trigger (Transact-SQL)」を参照してください。

即時更新

  • 即時更新サブスクリプションでは、サブスクライバでの変更は、パブリッシャに反映され、Microsoft 分散トランザクション コーディネータ (MS DTC) を使用して適用されます。パブリッシャおよびサブスクライバに MS DTC がインストールおよび構成されていることを確認してください。詳細については、Windows のマニュアルを参照してください。

  • 即時更新サブスクリプションで使用されるトリガでは、変更をレプリケートするためにパブリッシャへ接続する必要があります。この接続の保護の詳細については、「更新サブスクリプションのセキュリティに関する注意点」を参照してください。

  • パブリケーションで、即時更新サブスクリプションおよびパブリケーション内のアーティクルに対する列フィルタが許容する場合は、既定値を持たず NULL にできない列をフィルタ選択により除外することはできません。

キュー更新

  • キュー更新サブスクリプションを受け入れるトランザクション パブリケーションの一部として、マージ パブリケーションのテーブルをパブリッシュすることはできません。

  • 主キーはすべてのキューでレコードを見つけるために使用されるので、キュー更新では主キーの列を更新しないでください。競合の解決方法がサブスクライバ優先であるとき、主キーの更新には注意が必要です。主キーの更新をパブリッシャとサブスクライバの両方で行うと、その結果は 2 つの行がそれぞれ異なる主キーを持つことになります。

  • データ型 SQL_VARIANT の列については、サブスクライバでデータが挿入または更新されると、データをサブスクライバからキューにコピーするときに、キュー リーダー エージェントによって次のようにマップされます。

    • BIGINT、DECIMAL、NUMERIC、MONEY、および SMALLMONEY は、NUMERIC にマップされます。

    • BINARY および VARBINARY は、VARBINARY データにマップされます。

競合の検出と解決

  • サブスクライバ優先の競合ポリシーの場合、主キー列への更新に対して、競合解決方法はサポートされません。

  • 外部キーの制約違反による競合は、レプリケーションでは解決されません。

    • 競合が予想されず、データが正常にパーティション分割されている (サブスクライバは同じ行を更新しない) 場合は、パブリッシャおよびサブスクライバで外部キーの制約を使用できます。

    • 競合が予想され、"サブスクライバ優先" の競合解決方法を使用する場合は、パブリッシャまたはサブスクライバで外部キーの制約は使用しないでください。"パブリッシャ優先" の競合解決方法を使用する場合は、サブスクライバで外部キーの制約は使用しないでください。