Updatable Subscriptions for Transactional Replication
適用対象: SQL Server 2008 (以降)
注意
この機能は、Microsoft SQL Server の将来のバージョンで削除されます。 新規の開発作業ではこの機能を使用しないようにし、現在この機能を使用しているアプリケーションは修正することを検討してください。
SQL Server 2014 では、トランザクション レプリケーションでは、更新可能なサブスクリプションとピア ツー ピア レプリケーションを使用したサブスクライバーでの更新がサポートされています。 2 種類の更新可能なサブスクリプションを以下に示します。
即時更新。 サブスクライバーのデータを更新するために、パブリッシャーとサブスクライバーを接続する必要があります。
キュー更新。サブスクライバーのデータを更新するために、パブリッシャーとサブスクライバーを接続する必要はありません。 サブスクライバーまたはパブリッシャーがオフラインでも更新できます。
サブスクライバーでデータが更新されると、更新はまずパブリッシャーに反映され、次に他のサブスクライバーに反映されます。 即時更新を使用した場合、変更は 2 フェーズ コミット プロトコルを使用して即時に反映されます。 キュー更新を使用した場合、変更はキューに格納されます。キューに登録されたトランザクションは、ネットワーク接続が可能であればいつでも、パブリッシャーで非同期に適用されます。 更新は非同期的にパブリッシャーに反映されるので、同じデータがそのパブリッシャーまたは別のサブスクライバーによって更新済みになると、更新の適用時に競合が生じる可能性があります。 競合の解決方法はパブリケーションの作成時に設定され、この方法に従って競合が検出されて解決されます。
パブリケーションの新規作成ウィザードで更新可能なサブスクリプションによるトランザクション パブリケーションを作成する場合は、即時更新およびキュー更新の両方が有効になります。 ストアド プロシージャによるパブリケーションを作成する場合は、どちらか一方または両方のオプションを有効にすることができます。 パブリケーションに対してサブスクリプションを作成する場合は、使用する更新モードを指定します。 必要に応じて、更新モードを切り替えることができます。 詳細については、以下の「更新モードの切り替え」を参照してください。
トランザクション パブリケーションの更新可能なサブスクリプションを有効にするには、「トランザクション パブリケーションの更新可能なサブスクリプションの有効化」をご覧ください。
トランザクション パブリケーションの更新可能なサブスクリプションを作成するには、「 Create an Updatable Subscription to a Transactional Publication」をご覧ください。
更新モードの切り替え
更新可能なサブスクリプションを使用する場合に、サブスクリプションに 1 つの更新モードを指定し、アプリケーションで別の更新モードが必要な場合はそちらに切り替えるように指定できます。 たとえば、サブスクリプションで即時更新を使用するが、システム障害でネットワークに接続できなくなった場合には、キュー更新に切り替えるように指定することができます。
注意
レプリケーションでは、自動的に更新モードの切り替えを行いません。 SQL Server Management Studioを使用して更新モードを設定するか、アプリケーションで sp_setreplfailovermode (Transact-SQL) を呼び出してモードを切り替える必要があります。
即時更新からキュー更新へ切り替えた場合、サブスクライバーとパブリッシャーが接続され、キュー リーダー エージェントがキューにあるすべての保留メッセージをパブリッシャーに適用するまで、即時更新に戻すことはできません。
更新モードを切り替えるには
更新モードを切り替えるには、両方の更新モードに対してパブリケーションとサブスクリプションを有効にしてから、必要に応じてこれらを切り替える必要があります。 詳細については、「
更新可能トランザクション サブスクリプションの更新モードの切り替え
更新可能なサブスクリプションの使用に関する注意点
更新サブスクリプションまたはキュー更新サブスクリプションに対してパブリケーションを有効にすると、このオプションをパブリケーションに対して無効にできません (サブスクリプションで使用する必要がない場合でも同様)。 このオプションを無効にするには、パブリケーションを削除し、新しいパブリケーションを作成する必要があります。
データの再パブリッシュはサポートされていません。
レプリケーションでは、追跡のため、パブリッシュされたテーブルに msrepl_tran_version 列を追加します。 追加したこの列により、すべての
INSERT
ステートメントには、列リストを含める必要があります。更新サブスクリプションをサポートするパブリケーションのテーブルでスキーマ変更を行うには、パブリッシャーおよびサブスクライバーでのテーブルの利用をすべて停止し、スキーマ変更を行う前に、保留中のデータの変更をすべてのノードに反映させる必要があります。 これにより、未完了のトランザクションが保留中のスキーマ変更と競合しません。 スキーマ変更がすべてのノードに反映されたら、パブリッシュされたテーブルの操作を再開できます。 詳細については、「レプリケーション トポロジの停止 (レプリケーション Transact-SQL プログラミング)」を参照してください。
更新モードを切り替える場合、サブスクリプションが初期化された後で、少なくとも 1 回はキュー リーダー エージェントを実行する必要があります (既定では、キュー リーダー エージェントは連続的に実行されます)。
サブスクライバー データベースが行方向にパーティション分割され、そのパーティションにパブリッシャーではなくサブスクライバーの行が入る場合は、サブスクライバーはそれ以前に存在した行を更新することはできません。 これらの行を更新しようとすると、エラーが返されます。 行はテーブルから削除され、パブリッシャーで追加されます。
サブスクライバーでの更新
サブスクライバーでの更新は、サブスクリプションの有効期限が切れていたり、アクティブでない場合でも、パブリッシャーに反映されます。 そのようなサブスクリプションは、削除または再初期化してください。
TIMESTAMP
またはIDENTITY
が使用され、これらの列が基本データ型としてレプリケートされる場合、列の値はサブスクライバーでは更新されません。text
、ntext
またはimage
値は、レプリケーションの変更の追跡トリガー内で挿入または削除されたテーブルから読み取ることができないため、サブスクライバーはこれらを更新または挿入できません。 同様に、WRITETEXT
やUPDATETEXT
を使用すると、サブスクライバーはtext
値やimage
値を更新したり挿入したりすることができません。これらのデータはパブリッシャーによって上書きされるからです。 ただし、text
列とimage
列を別々のテーブルに分けて、トランザクション内で 2 つのテーブルを変更することはできます。サブスクライバーで大きなオブジェクト更新するには、
text
、ntext
、image
のデータ型の代わりに、varchar(max)
、nvarchar(max)
、varbinary(max)
のデータ型をそれぞれに使用します。一意なキー (主キーを含む) に対する更新によって重複が生じる場合 (たとえば、
UPDATE <column> SET <column> =<column>+1
などの形式による更新)、その更新を行うことはできません。その更新は一意性違反のため拒否されます。 これは、サブスクライバーで行われた SET 更新が、レプリケーションによって、影響される各行に対する個々のUPDATE
ステートメントとして反映されるからです。サブスクライバー データベースが行方向にパーティション分割されていて、行を含むパーティションがサブスクライバーにはあっても、パブリッシャーにはない場合、この既存の行をサブスクライバーは更新できません。 これらの行を更新しようとすると、エラーが返されます。 この行は、テーブルから削除し、再び挿入する必要があります。
ユーザー定義トリガー
サブスクライバーでアプリケーションがトリガーを必要とする場合、パブリッシャーおよびサブスクライバーで
NOT FOR REPLICATION
オプションを使用してトリガーを定義する必要があります。 これにより、トリガーは元のデータの変更に対してのみ起動され、その変更がレプリケートされるときには起動されません。ユーザー定義トリガーは、レプリケーション トリガーがテーブルを更新するときには起動されません。 これは、ユーザー定義トリガーの本文で、プロシージャ
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
データにマップされます。
競合の検出と解決
サブスクライバー優先の競合ポリシーの場合、主キー列への更新に対して、競合解決方法はサポートされません。
外部キーの制約違反による競合は、レプリケーションでは解決されません。
競合が予想されず、データが正常にパーティション分割されている (サブスクライバーは同じ行を更新しない) 場合は、パブリッシャーおよびサブスクライバーで外部キーの制約を使用できます。
競合が予想され、"サブスクライバー優先" の競合解決方法を使用する場合は、パブリッシャーまたはサブスクライバーで外部キーの制約は使用しないでください。"パブリッシャー優先" の競合解決方法を使用する場合は、サブスクライバーで外部キーの制約は使用しないでください。
参照
ピア ツー ピア トランザクション レプリケーション
トランザクション レプリケーション
データとデータベース オブジェクトのパブリッシュ
パブリケーションのサブスクライブ