データベース ミラーリングまたは AlwaysOn 可用性グループではサポートされない複数データベースにまたがるトランザクション (SQL Server)

複数のデータベースにまたがるトランザクションおよび分散トランザクションは、AlwaysOn 可用性グループやデータベース ミラーリングではサポートされません。 これは、次の理由により、トランザクションの原子性と整合性を保証できないためです。

  • 複数データベースにまたがるトランザクション: それぞれのデータベースが別々にコミットします。 そのため、複数のデータベースが 1 つの可用性グループに属している場合でも、一方のデータベースがトランザクションをコミットした後、もう一方のデータベースがコミットする前に、フェールオーバーが発生する可能性があります。 データベース ミラーリングの場合、この問題はさらに複雑です。フェールオーバーの後、ミラー化されたデータベースは、もう一方のデータベースとは異なるサーバー インスタンスに存在することが多いためです。両方のデータベースが同じ 2 つのパートナー間でミラーリングされていても、両方のデータベースが同時にフェールオーバーされる保証はありません。

  • 分散トランザクションの場合: フェールオーバー後、新しいプリンシパル サーバー/プライマリ レプリカは、以前のプリンシパル サーバー/プライマリ レプリカの分散トランザクション コーディネーターに接続できません。 このため、新しいプリンシパル サーバー/プライマリ レプリカはトランザクションの状態を取得できません。

次に示すデータベース ミラーリングの例では、論理的な不一致が発生するしくみについて説明します。 この例では、アプリケーションは複数データベースにまたがるトランザクションを使用して 2 行のデータを挿入します。一方の行は、ミラー化されたデータベース A 内のテーブルに挿入され、もう一方の行は、別のデータベース B 内のテーブルに挿入されます。 データベース A は、自動フェールオーバーを伴う高い安全性モードでミラー化されています。 トランザクションがコミットされている間、データベース A は使用できなくなり、ミラーリング セッションはデータベース A のミラーに自動的にフェールオーバーされます。

フェールオーバー後、複数データベースにまたがるトランザクションは、データベース B では正常にコミットされますが、フェールオーバーされたデータベースではコミットされない場合があります。 これは、障害発生前に、複数データベースにまたがるトランザクションのログがデータベース A の元のプリンシパル サーバーからミラー サーバーに送信されなかった場合に発生します。 フェールオーバー後、そのトランザクションは新しいプリンシパル サーバーに存在しなくなります。 データベース B に挿入されたデータはそのまま保たれますが、データベース A に挿入されたデータは失われているため、データベース A と B は一致しなくなります。

同様の状況は、MS DTC トランザクションを使用する際に発生する場合があります。 たとえば、フェールオーバー後、新しいプリンシパルが MS DTC にアクセスします。 ただし、MS DTC は、新しいプリンシパル サーバーを認識せず、"コミットの準備が整った" トランザクションを終了します。これらのトランザクションは、他のデータベースでコミットされていると見なされます。