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

適用対象:SQL Server

この機能は、SQL Server 2012 から 2016 のバージョンでサポートされています。 この機能は、 SQL Serverの将来のバージョンで削除される予定です。 新規の開発作業ではこの機能を使用しないようにし、現在この機能を使用しているアプリケーションは修正することを検討してください。

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

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

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

サブスクライバーでデータを更新すると、まずPublisherに更新され、その後他のサブスクライバーに更新されます。 即時更新を使う場合、変更は二段階コミットプロトコルで即座に処理されます。 キュー型更新を使うと、変更はキューに入ります。 キューに入ったトランザクションは、ネットワーク接続が利用可能な場合に非同期的にPublisherに送られます。 更新は非同期でPublisherに届くため、同じデータがPublisherや他の加入者によって更新される可能性があり、更新を適用する際に競合が発生することがあります。 システムは、出版物作成時に設定した紛争解決ポリシーに従って、競合を検出し解決します。

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

トランザクション出版物の更新可能な購読を有効にするには、「 取引出版物の購読更新を有効にする」を参照してください。

トランザクション出版物の更新可能な購読を作成するには、「 取引出版物の更新可能な購読を作成(Management Studio)」をご覧ください。

更新モード間の切り替え

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

レプリケーションは更新モード間で自動的に切り替わるわけではありません。 SQL Server Management Studioで更新モードを設定するか、アプリケーション内のsp_setreplfailovermode(Transact-SQL)を呼び出してモードを切り替えてください。

即時更新からキュー更新に切り替えた場合、SubscriberとPublisherが接続し、Queue Readerエージェントがキュー内の保留中のすべてのメッセージをPublisherに適用するまで即時更新に戻せません。

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

更新モードを切り替えるには、両方の更新モードで出版とサブスクリプションを有効にし、必要に応じて切り替えてください。 詳細については、以下を参照してください。
更新可能トランザクション サブスクリプションの更新モードの切り替え

更新可能なサブスクリプションを使用する際の考慮事項

  • 購読の更新用に出版物を有効化したり、更新中のサブスクリプションをキューにしたりした後は、その出版物のオプションを無効にすることはできません(ただし、購読者は必ずしも使う必要はありません)。 このオプションを無効にするには、出版物を削除して新しいものを作成してください。

  • データの再公開はサポートされていません。

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

  • サブスクリプションの更新をサポートする出版物内のテーブルでスキーマを変更したい場合は、PublisherおよびSubscribersでテーブル上のすべての活動を停止し、スキーマ変更を行う前に保留中のデータ変更をすべてのノードに伝播してください。 このプロセスにより、未処理のトランザクションが保留中のスキーマ変更と競合しないようにします。 スキーマの変更がすべてのノードに伝播した後、公開されたテーブルでの活動が再開されます。 詳細については、「レプリケーション トポロジの停止 (レプリケーション Transact-SQL プログラミング)」を参照してください。

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

  • Subscriberデータベースが水平に分割されていて、そのパーティション内にSubscriber側に存在する行がPublisher側に存在しない場合、Subscriberは既存の行を更新できません。 これらの行を更新しようとすると、エラーが返されます。 テーブルから行を削除し、その後Publisherで追加してください。

  • キュー更新サブスクライバーを使用したトランザクション レプリケーションでは、一意のフィルター選択インデックスを使用すると、パフォーマンスが低下することがあります。 もし一意なフィルタリングインデックスを持つ記事で競合が発生した場合、その競合解決によって、ユニークフィルタドインデックスでカバーされていない行に対して、サブスクライバー側に追加の削除や挿入が発生します。

サブスクライバーでの更新

  • 購読者側の更新は、契約が切れていたり非アクティブであっても、Publisherに伝播されます。 そのようなサブスクリプションは必ず解約または再初期化してください。

  • TIMESTAMPIDENTITYカラムを使い、それらをベースデータ型として複製する場合は、サブスクライバーでこれらのカラムの値を更新しないでください。

  • 登録者は テキストnテキスト画像 の値を更新または挿入できません。なぜなら、レプリケーションの変更追跡トリガーが挿入または削除されたテーブルから読み取れないからです。 同様に、WRITETEXTUPDATETEXTを使ってテキスト画像の値を更新・挿入することはできません。なぜなら、Publisherがデータを上書きしてしまうからです。 代わりに、 テキスト画像 の列を別々のテーブルに分割し、トランザクション内で両方のテーブルを修正することができました。

    サブスクライバーで大きなオブジェクトを更新するには、テキストntext画像のデータ型の代わりにvarchar(max)、nvarchar(max)、varbinary(max)というデータ型をそれぞれ使用してください。

  • 一意キー(プライマリキーを含む)への更新で重複が生じる場合、例えばフォーム UPDATE <column> SET <column> =<column>+1の更新は許可されず、一意性違反のために拒否されます。 サブスクライバーで行われたセットの更新は、影響を受ける各行ごとに個別の UPDATE 文としてレプリケーションによって伝播します。

  • サブスクライバーデータベースが水平に分割されていて、そのパーティションにSubscriberには存在するがPublisherには存在しない行が含まれている場合、Subscriberは既存の行を更新できません。 これらの行を更新しようとすると、エラーが返されます。 これらの行を削除して再挿入してください。

ユーザー定義トリガー

  • アプリケーションがサブスクライバーでトリガーを必要とする場合は、PublisherとサブスクライバーのNOT FOR REPLICATIONオプションでトリガーを定義してください。 このオプションにより、トリガーは元のデータ変更時のみ発生し、レプリケーションが変更を伝播した際には発生しません。

    レプリケーショントリガーがテーブルを更新した際にユーザー定義トリガーが発動しないようにしてください。 ユーザー定義トリガーの本文でプロシージャ sp_check_for_sync_trigger を呼び出します。 詳細については、「sp_check_for_sync_trigger (Transact-SQL)」を参照してください。

即時更新

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

  • 即時更新サブスクリプションが使用するトリガーは、変更を複製するためにPublisherへの接続が必要です。

  • もし出版物が即時更新の購読を許可していて、その出版物の記事にカラムフィルターがある場合、デフォルトなしで非空の列を除外することはできません。

更新待ち

  • マージパブリケーションに含まれるテーブルを、サブスクリプションのキュー付き更新を許可するトランザクションパブリケーションの一部として公開することはできません。

  • キュー更新時はプライマリキーの列を更新しないでください。プライマリキーはすべてのクエリのレコードロケータとして機能します。 コンフリクト解決ポリシーが「加入者の勝利」に設定されている場合、プライマリキーの更新には注意してください。 PublisherとSubscriberの両方が主キーを更新すると、結果として異なる主キーを持つ2行になります。

  • データ型 SQL_VARIANTの列の場合:サブスクライバーでデータが挿入または更新された際、キューリーダーエージェントはサブスクライバーからキューにデータをコピーする際に次のようにマッピングします。

    • BIGINTDECIMALNUMERICMONEY、およびSMALLMONEYは、NUMERICに対応します。

    • BINARY および VARBINARYVARBINARY データに対応します。

紛争検出と解決

  • 購読者が勝つ競合ポリシーについて:競合解決はプライマリキーカラムの更新をサポートしていません。

  • レプリケーションは外部鍵制約の障害による競合を解決しません:

    • 競合が予想されず、データが適切に分割されている(Subscriberが同じ行を更新しない)場合は、PublisherとSubscribersの両方に外部キー制約を使いましょう。

    • 競合が予想される場合は、「Subscriber wins」の競合解決を使う場合は、PublisherやSubscriberで外部キー制約を使用しないでください。 「Publisher wins」の競合解決を使う場合は、サブスクライバーで外部キー制約は使わないでください。