データベース ミラーリングの使用 (JDBC)

データベース ミラーリングは、主にデータベースの可用性とデータの冗長性を向上するためのソフトウェア ソリューションです。 Microsoft SQL Server 2005 JDBC Driver は、データベース ミラーリングを暗黙的にサポートするため、データベース用に構成されていれば、開発者がコードを記述したり、その他の操作を行ったりする必要はありません。

データベース ミラーリングは、データベースごとに実装され、スタンバイ サーバー上に SQL Server 2005 運用データベースのコピーを保持します。 このサーバーは、データベース ミラーリング セッションの構成と状態によって、ホット スタンバイ サーバーまたはウォーム スタンバイ サーバーのいずれかになります。 ホット スタンバイ サーバーは、コミットされたトランザクションを損失することなくラピッド フェールオーバーをサポートし、ウォーム スタンバイ サーバーは、サービス強制をサポートします (データ損失の可能性があります)。

運用データベースはプリンシパル データベースと呼ばれ、スタンバイ コピーはミラー データベースと呼ばれます。 プリンシパル データベースとミラー データベースは、SQL Server 2005 の別々のインスタンス (サーバー インスタンス) 上に存在する必要があります。また、可能であれば、これらのデータベースは別々のコンピュータ上に配置してください。

プリンシパル サーバーと呼ばれる運用サーバー インスタンスは、ミラー サーバーと呼ばれるスタンバイ サーバー インスタンスと通信します。 プリンシパル サーバーとミラー サーバーは、データベース ミラーリング セッション内でパートナーとして機能します。 プリンシパル サーバーで障害が発生した場合、ミラー サーバーはフェールオーバーと呼ばれる処理を通じて、ミラー サーバーのデータベースをプリンシパル データベースにできます。 たとえば、Partner_A と Partner_B は 2 つのパートナー サーバーで、最初はプリンシパル サーバーの Partner_A にプリンシパル データベース、ミラー サーバーの Partner_B にミラー データベースが存在するとします。 Partner_A がオフラインになった場合は、Partner_B 上のデータベースをフェールオーバーして、現在のプリンシパル データベースにできます。 Partner_A がミラーリング セッションに再び参加すると、Partner_A はミラー サーバーとなり、Partner_A のデータベースはミラー データベースとなります。

Partner_A サーバーが破損して修復不可能な場合は、Partner_C サーバーをオンラインにして、プリンシパル サーバーとなった Partner_B のミラー サーバーとして機能させることができます。 ただし、このシナリオでは、データベース ミラーリング構成で使用される新しいサーバー名で接続文字列プロパティが更新されるように、クライアント アプリケーションにプログラミング ロジックを含める必要があります。 含めない場合、サーバーへの接続に失敗する可能性があります。

代替のデータベース ミラーリング構成では、さまざまなレベルのパフォーマンスおよびデータ安全性が提供され、異なる形式のフェールオーバーがサポートされます。 詳細については、SQL Server オンライン ブックの「データベース ミラーリングの概要」を参照してください。

プログラムに関する考慮事項

プリンシパル データベース サーバーで障害が発生すると、クライアント アプリケーションは API 呼び出しの応答としてエラーを受信します。これは、データベースへの接続が失われたことを示します。 この問題が発生すると、データベースに対するコミットされていない変更はすべて失われ、現在のトランザクションはロールバックされます。 このような場合、アプリケーションでは接続を閉じて (または、データ ソース オブジェクトを解放して) から、再び開く必要があります。 接続時に、新しい接続はプリンシパル サーバーとなったミラー データベースに透過的にリダイレクトされます。クライアントが接続文字列またはデータ ソース オブジェクトを変更する必要はありません。

接続が最初に確立されると、プリンシパル サーバーはフェールオーバー パートナーの ID を、フェールオーバー発生時に使用されるクライアントに送信します。 アプリケーションが障害の発生したプリンシパル サーバーと最初の接続を確立しようとするとき、フェールオーバー パートナーの ID はクライアントに通知されていません。 クライアントがこのシナリオに対処できるように、failoverPartner 接続文字列プロパティ、およびオプションで setFailoverPartner データ ソース メソッドを使用することで、クライアントはフェールオーバー パートナーの ID を独自に指定できます。 クライアント プロパティはこのシナリオでのみ使用されます。プリンシパル サーバーが利用可能な場合は使用されません。

注意

接続文字列またはデータ ソース オブジェクトで failoverPartner が指定されている場合は、databaseName プロパティも設定する必要があります。これが設定されていないと、例外がスローされます。 failoverPartner および databaseName が明示的に指定されていないと、プリンシパル データベース サーバーに障害が発生した場合に、アプリケーションがフェールオーバーを実行しません。 つまり、透過的なリダイレクトは、failoverPartner および databaseName が明示的に指定された接続に対してのみ機能します。 failoverPartner およびその他の接続文字列プロパティの詳細については、「接続プロパティの設定」を参照してください。

クライアントで指定されたフェールオーバー パートナー サーバーが、指定されたデータベースのフェールオーバー パートナーの役割を担っているサーバーを指していない場合、接続はサーバーによって拒否されます。 SQLServerDataSource クラスは getFailoverPartner メソッドを提供しますが、このメソッドは接続文字列または setFailoverPartner メソッドで指定されたフェールオーバー パートナーの名前のみを返します。 現在使用されている実際のフェールオーバー パートナーの名前を取得するには、次の Transact-SQL ステートメントを使用します。

SELECT m.mirroring_role_DESC, m.mirroring_state_DESC,
m.mirroring_partner_instance FROM sys.databases as db,
sys.database_mirroring AS m WHERE db.name = 'MirroringDBName'
AND db.database_id = m.database_id

注意

ミラーリング データベースの名前を使用するには、このステートメントを変更する必要があります。

接続の最初の試行が失敗した場合に備えて、接続文字列を更新するか、または再試行の戦略を立てるために、パートナー情報をキャッシュすることを検討してください。

次の例では、最初にプリンシパル サーバーへの接続が試行されます。 接続に失敗して例外がスローされた場合、ミラー サーバーへの接続が試行されます。ミラー サーバーは新しいプリンシパル サーバーに昇格している可能性があります。 接続文字列での failoverPartner プロパティの使用に注意してください。

import java.sql.*;

public class clientFailover {

   public static void main(String[] args) {

      // Create a variable for the connection string.
      String connectionUrl = "jdbc:sqlserver://serverA:1433;" +
         "databaseName=AdventureWorks;integratedSecurity=true;" +
         "failoverPartner=serverB";

      // Declare the JDBC objects.
      Connection con = null;
      Statement stmt = null;

      try {
         // Establish the connection to the principal server.
         Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");
         con = DriverManager.getConnection(connectionUrl);
         System.out.println("Connected to the principal server.");

         // Note that if a failover of serverA occurs here, then an
         // exception will be thrown and the failover partner will
         // be used in the first catch block below.

         // Create and execute an SQL statement that inserts some data.
         stmt = con.createStatement();

         // Note that the following statement assumes that the 
         // TestTable table has been created in the AdventureWorks
         // sample database.
         stmt.executeUpdate("INSERT INTO TestTable (Col2, Col3) VALUES ('a', 10)");
      }

      // Handle any errors that may have occurred.
      catch (SQLException se) {
         try {
            // The connection to the principal server failed,
            // try the mirror server which may now be the new
            // principal server.
            System.out.println("Connection to principal server failed, " +
            "trying the mirror server.");
            con = DriverManager.getConnection(connectionUrl);
            System.out.println("Connected to the new principal server.");
            stmt = con.createStatement();
            stmt.executeUpdate("INSERT INTO TestTable (Col2, Col3) VALUES ('a', 10)");
         }
         catch (Exception e) {
            e.printStackTrace();
         }
      }
      catch (Exception e) {
         e.printStackTrace();
      }
      // Close the JDBC objects.
      finally {
         if (stmt != null) try { stmt.close(); } catch(Exception e) {}
         if (con != null) try { con.close(); } catch(Exception e) {}
      }
   }
}

参照

その他のリソース

JDBC ドライバによる SQL Server への接続