28 Javaのアプリケーション・コンティニュイティ

アプリケーション・コンティニュイティは、汎用目的のアプリケーションから独立したソリューションを提供します。これにより、計画済または計画外の停止発生後にアプリケーションからの作業のリカバリが可能になります。停止は、修復、構成変更またはパッチ適用後のシステム、通信またはハードウェアに関連している可能性があります。

基礎となるソフトウェア、ハードウェア、通信および記憶域レイヤーが停止すると、アプリケーションの実行が失敗することがあります。最悪の場合、ログオン・ストーム脚注1を処理するために、中間層のサーバーを再起動しなければならないことがあります。アプリケーション・コンティニュイティ機能は、データベースの停止をアプリケーションにマスクし、エンド・ユーザーがそのような停止にさらされないため、このような問題を克服するのに役立ちます。

ノート:

  • この機能を使用するには、トランザクション・ガードを使用する必要があります。

  • アプリケーション・コンティニュイティは、Oracle JDBC Thinドライバの機能であり、JDBC OCIドライバではサポートされていません。

この章では、次の項でアプリケーション・コンティニュイティに関するJDBCの側面について説明します。

28.1 Java用のアプリケーション・コンティニュイティに対するOracle JDBCの構成について

oracle.jdbc.replay.OracleDataSourceImploracle.jdbc.replay.OracleConnectionPoolDataSourceImplまたはoracle.jdbc.replay.driver.OracleXADataSourceImplデータソースを使用して、JDBC接続を取得する必要があります。oracle.jdbc.replay.OracleDataSourceImploracle.jdbc.replay.OracleConnectionPoolDataSourceImplの両方をスタンドアロン方式で使用できます。あるいは、ユニバーサル接続プール(UCP)またはOracle WebLogic Server接続プールなどの接続プール用コネクション・ファクトリとして構成することもできます。

Oracle Database 12cリリース2 (12.2.0.1)以降、JDBCリプレイ・ドライバでは、新しいデータソース(XAリプレイ・データソース)が提供されています。これは、JDBC操作のリプレイをサポートしており、高速接続フェイルオーバー、ランタイム接続ロード・バランシングおよびすべてのタイプのRACインスタンス・アフィニティを含め、すべてのOracle RAC機能に対してUCPデータソースとWebLogicのアクティブなGridLinkの単一プールのデータソースとともに動作します。このデータソースを使用するには、oracle.jdbc.replay.OracleXADataSourceインタフェースを実装する必要があります。実際のデータソースの実装クラスは、oracle.jdbc.replay.driver.OracleXADataSourceImplです。接続ファクトリとして、実装クラスをUCPデータソースとOracle WebLogic Server GridLinkデータソースに指定できます。JNDIのファクトリ・クラスは、oracle.jdbc.replay.OracleXADataSourceFactoryです。

ノート:

  • XAリプレイ・データソースでは、構成可能なリプレイ・モードが提供されていません。リプレイを有効にするには、リプレイ・データソースを使用して、サーバー側のデータベース・サービス上でFAILOVER_TYPETRANSACTIONに設定する必要があります(設定されていない場合)。

  • Oracle Databaseリリース18c以降、FAILOVER_TYPEAUTOに設定して、透過的アプリケーション・コンティニュイティを使用することもできます。

  • リプレイを動的に有効および無効にするには、リプレイ接続プロキシで使用可能な別のAPIを使用する必要があります。XAリプレイ・データソースでは、接続プーリングが提供されていません。getXAConnectionメソッドをコールすると、新しいJDBC XAConnectionプロキシが動的に作成されます。これにより、代理として新しいJDBC物理接続が保持されます。代理となるのはOracle JDBCドライバ・オブジェクトです。

次のコードでは、スタンドアロンのJDBCアプリケーションでのoracle.jdbc.replay.OracleDataSourceImplおよびoracle.jdbc.replay.OracleConnectionPoolDataSourceImplの使用方法を示します。

import java.sql.Connection;
import javax.sql.PooledConnection;
import oracle.jdbc.OracleConnection;
import oracle.jdbc.replay.OracleDataSourceFactory;
import oracle.jdbc.replay.OracleDataSource;
import oracle.jdbc.replay.OracleConnectionPoolDataSource;
 
...
{
......
OracleDataSource rds = OracleDataSourceFactory.getOracleDataSource();
rds.setUser(user);
rds.setPassword(passwd);
rds.setURL(url);
......  // Other data source configuration like callback, timeouts, etc.
 
Connection conn = rds.getConnection();
((OracleConnection) conn).beginRequest();  // Explicit request begin
......  // JDBC calls protected by Application Continuity
((OracleConnection) conn).endRequest();  // Explicit request end
conn.close();
 
OracleConnectionPoolDataSource rcpds = OracleDataSourceFactory.getOracleConnectionPoolDataSource();
rcpds.setUser(user);
rcpds.setPassword(passwd);
rcpds.setURL(url);
......  // other data source configuration like callback, timeouts, and so on
 
PooledConnection pc = rcpds.getPooledConnection();
Connection conn2 = pc.getConnection();  // Implicit request begin
......  // JDBC calls protected by Application Continuity
conn2.close();  // Implicit request end
......

接続URLの使用時には次の点に注意する必要があります。

  • 接続URLで、常にThinドライバを使用します。

  • 常にサービスに接続します。instance_nameまたはSIDは使用しないでください。これらを使用しても、既知の適切なインスタンスにマッピングされません。また、SIDは非推奨です。

  • クライアントのADDRESS_LIST内のアドレスがデータベースのREMOTE_LISTENER設定と一致しない場合、接続が行われず、「サービスが見つかりません」というメッセージが表示されます。このため、クライアントのADDRESS_LIST内のアドレスはデータベースのREMOTE_LISTENER設定と一致する必要があります

    • REMOTE_LISTENERSCAN_VIPに設定されている場合、ADDRESS_LISTにはSCAN_VIPが使用されます。

    • REMOTE_LISTENERがホストVIPに設定されている場合、ADDRESS_LISTでは同じホストVIPが使用されます。

    • REMOTE_LISTENERSCAN_VIPとホストVIPの両方に設定されている場合、ADDRESS_LISTにはSCAN_VIPおよび同じホストVIPが使用されます

      ノート:

      リリース11.2より前のOracleクライアントの場合、SCANを使用するには、ADDRESS_LISTをアップグレードする必要があります。つまり、ADDRESS_LISTを3つのSCAN IPアドレスに対応する3つのADDRESSエントリにまで拡張します。

      Database Upgrade Assistantを使用して以前のリリースからアップグレードされるデータベースにこのようなクライアントが接続する場合、HOST VIPに設定されたこれらのクライアントのADDRESS_LISTを保持する必要があります。ただし、REMOTE_LISTENERONLY SCANに変更されると、またはクライアントが新しくインストールされたOracle Database 12c リリース1 (REMOTE_LISTENERONLY SCAN)に移動されると、完全なサービス・マップが取得されず、接続できないことがあります。

  • 接続文字列にRETRY_COUNTRETRY_DELAYCONNECT_TIMEOUTおよびTRANSPORT_CONNECT_TIMEOUTパラメータを設定します。Oracle Databaseリリース12.1.0.2以降、これは、JDBC Thinドライバ接続を構成する際の一般的な推奨事項です。これらの設定により、ランタイム時、リプレイ時、および計画済停止の作業排出時に新規接続の取得効率が向上します。

    CONNECT_TIMEOUTは、sqlnet.oraファイル内のSQLNET.OUTBOUND_CONNECT_TIMEOUTパラメータと等価であり、完全接続に適用されます。TRANSPORT_CONNECT_TIMEOUTパラメータはADDRESSパラメータに従って適用されます。サービスがフェイルオーバーまたは再起動に対して登録されていない場合、SCANを使用する際に再試行が重要になります。たとえば、SCANアドレスを指すリモート・リスナーを使用する場合、次の設定を使用する必要があります。

    jdbc:oracle:thin:@(DESCRIPTION = 
     (TRANSPORT_CONNECT_TIMEOUT=3000)
     (RETRY_COUNT=20)(RETRY_DELAY=3)(FAILOVER=ON)
     (ADDRESS_LIST =(ADDRESS=(PROTOCOL=tcp)
      (HOST=CLOUD-SCANVIP.example.com)(PORT=5221)) 
     (CONNECT_DATA=(SERVICE_NAME=orcl))) 
     
    REMOTE_LISTENERS=CLOUD-SCANVIP.example.com:5221 
    

    同様に、データベースでVIPを指すリモート・リスナーを使用する場合、次の設定を使用する必要があります。

    jdbc:oracle:thin:@(DESCRIPTION = 
    (TRANSPORT_CONNECT_TIMEOUT=3000)
    (CONNECT_TIMEOUT=60)(RETRY_COUNT=20)(RETRY_DELAY=3)(FAILOVER=ON)
     (ADDRESS_LIST=
     (ADDRESS=(PROTOCOL=tcp)(HOST=CLOUD-VIP1.example.com)(PORT=5221) )
    (ADDRESS=(PROTOCOL=tcp)(HOST=CLOUD-VIP2.example.com)(PORT=5221) )
     (ADDRESS=(PROTOCOL=tcp)(HOST=CLOUD-VIP3.example.com)(PORT=5221) )) 
    (CONNECT_DATA=(SERVICE_NAME=orcl)))
    
    REMOTE_LISTENERS=CLOUD-VIP1.example.com:5221 
    

    関連項目:

関連トピック

28.1.1 アプリケーション・コンティニュイティでの具象クラスのサポート

Oracle Databaseリリース18c以降、JDBCドライバは、アプリケーション・コンティニュイティで次の具象クラスをサポートします。

  • oracle.sql.CLOB

  • oracle.sql.NCLOB

  • oracle.sql.BLOB

  • oracle.sql.BFILE

  • oracle.sql.STRUCT

  • oracle.sql.REF

  • oracle.sql.ARRAY

28.2 Java用のアプリケーション・コンティニュイティに対するOracle Databaseの構成について

Java用のアプリケーション・コンティニュイティを使用するには、次のようにOracle Databaseを構成する必要があります。

  • Oracle Database 12cリリース1 (12.1)以上を使用します

  • Oracle Real Application Clusters (Oracle RAC)またはOracle Data Guardを使用している場合、Oracle Notification System(ONS)を使用してFANを構成し、Oracle WebLogic Serverまたはユニバーサル接続プール(UCP)と通信するようにします。

  • すべてのデータベース処理に対してアプリケーション・サービスを使用します。サービスを作成するには、次の操作を実行します。

    • Oracle RACを使用している場合、SRVCTLコマンドを実行します。

    • Oracle RACを使用していない場合、DBMS_SERVICEパッケージを使用します。

  • リプレイおよびロード・バランシングに必要なプロパティをサービスに設定します。たとえば、次のように設定します。

    • aq_ha_notifications = TRUE: FAN通知を有効にします

    • FAILOVER_TYPE = TRANSACTIONまたはFAILOVER_TYPE = AUTO: アプリケーション・コンティニュイティを使用する場合

    • トランザクション・ガードを有効にする場合: COMMIT_OUTCOME = TRUE

    • リプレイが発生する期間(秒)を設定する場合: REPLAY_INITIATION_TIMEOUT = 900

    • FAILOVER_RETRIES = 30: リプレイごとに接続の再試行回数を指定します

    • FAILOVER_DELAY = 10: 接続の再試行間の遅延時間を秒単位で設定します

    • GOAL = SERVICE_TIME (Oracle RACを使用している場合、これが推奨設定です。)

    • CLB_GOAL = LONG: 通常、クローズしたワークロードに便利です。Oracle RACを使用している場合、これが推奨設定です。他のほとんどのワークロードの場合、SHORTが推奨設定です。

  • データベース・サービス(つまり、DB_NAMEまたはDB_UNIQUE_NAMEに対応するデフォルトのサービス)は使用しないでください。このサービスは、Oracle Enterprise ManagerおよびDBA用として予約されています。高可用性のためにデータベース・サービスを使用することは推奨していません。これは、このサービスについて次の作業を行うことができないためです。

    • 有効化と無効化

    • Oracle RACへの再配置

    • Oracle Data Guardへのスイッチオーバー

関連項目:

アプリケーション・コンティニュイティの操作および使用方法の詳細は、『Oracle Database開発ガイド』を参照してください。

28.3 アプリケーション・コンティニュイティにおけるXAデータソースのサポート

Oracle Database 12cリリース2 (12.2.0.1)では、非XAデータソース(javax.sql.DataSource)と同様に、Oracle XAデータソース(javax.sql.XADataSource)をサポートすることによって、アプリケーション・コンティニュイティを強化する新しい機能が導入されました。JDBCとJava Transaction API (JTA)の両方を使用すると、JDBC接続がローカル・トランザクションにもグローバル/XAトランザクションにも同じように参加できます。ただし、多数のカスタマ・アプリケーションがXAデータソースから接続を取得しますが、これらの接続を使用するのはローカル・トランザクションを実行する場合のみです。新機能のアプリケーション・コンティニュイティでは、グローバル/XAトランザクションに昇格可能なローカル・トランザクションを含め、ローカル・トランザクション以外のXA対応のデータソースを使用するアプリケーションにも対応しています。したがって、フェイルオーバーおよびフォワードリカバリなどのアプリケーション・コンティニュイティの利点がこれらのアプリケーションに拡張されました。

ノート:

この機能を使用するには、トランザクション・ガード12.2を使用する必要があります。

基礎となる物理接続がグローバル/XAトランザクションに参加したり、XA操作を行うときは常に、リプレイはその接続で無効になっています。他のすべてのXA操作は正常に機能しますが、アプリケーションではアプリケーション・コンティニュイティによる保護が得られません。

前述の理由でリプレイが接続で無効になると、次のリクエストが開始されるまで無効のままです。グローバル/XAトランザクション・モードからローカル・トランザクション・モードに切り替えても、接続でリプレイは自動的に有効になりません。

次のコードでは、接続がOracleXADataSourceから取得された場合に、ローカル・トランザクションからリプレイをサポートし、XAトランザクションに対して無効にする方法を示します。

import javax.transaction.xa.*;
import oracle.jdbc.replay.OracleXADataSource;
import oracle.jdbc.replay.OracleXADataSourceFactory;
import oracle.jdbc.replay.ReplayableConnection;

OracleXADataSource xards = OracleXADataSourceFactory.getOracleXADataSource();
xards.setURL(connectURL);
xards.setUser(<user_name>);
xards.setPassword(<password>);
XAConnection xaconn = xards.getXAConnection();

// Implicit request begins
Connection conn = xaconn.getConnection(); 


/* Local transaction case */
// Request-boundary detection OFF
((ReplayableConnection) conn).beginRequest();    
conn.setAutoCommit(false);
PreparedStatement pstmt=conn.prepareStatement(“select cust_first_name,cust_last_name from customers where customer_id=1");
ResultSet rs=pstmt.executeQuery();

// Outage happens at this point
// Replay happens at this point
rs.next();
rs.close();
pstmt.close();
((ReplayableConnection) conn).endRequest();
...

/* Global/XA transaction case */
((ReplayableConnection) conn).beginRequest();
conn.setAutoCommit(false);
XAResource xares = xaconn.getXAResource();
Xid xid = createXid();

// Replay is disabled here
xares.start(xid, XAResource.TMNOFLAGS);    
conn.prepareStatement(“INSERT INTO TEST_TAB VALUES(200, 'another new record')”);

// outage happens at this point
try {

//No replay here and throws exception
conn.executeUpdate();
}

// sqlrexc.getNextException() shows the reason for the replay failure
catch (SQLRecoverableException sqlrexc) {
    
    …...
}

28.4 Java用のアプリケーション・コンティニュイティにおけるリクエスト境界の識別について

リクエストは、アプリケーション・コンティニュイティによって保護されているOracle Databaseへの物理的な接続における作業の単位です。リクエスト境界は、ユースケースのシナリオによって異なります。リクエストが開始するのは接続がユニバーサル接続プール(UCP)またはWebLogic Server接続プールから流用されているときで、終了するのは接続が接続プールに返却されたときです。

JDBCドライバには、oracle.jdbc.OracleConnectionインタフェースで明示的なリクエスト境界宣言APIのbeginRequestおよびendRequestが用意されています。これらのAPIを使用すると、アプリケーション、フレームワークおよび接続プールが境界ポイントをJDBCリプレイ・ドライバに示すことができます。この境界ポイントで、安全にコール履歴を解放し、前のリクエストでリプレイが無効になっていた場合にこれを有効にすることができます。リクエストの終了時に、JDBCリプレイ・ドライバは、APIがコールされた接続について記録された履歴を削除します。これによって、アプリケーションは接続をプールに返却しないで延長して同じ接続を使用するので、メモリー消費がさらに節約されます。

接続プールが動作するには、必要な場合にアプリケーションが接続を取得し、使用していない場合に接続を解放する必要があります。これによって、リクエスト境界をより正しく見積もり、透過的に提供できます。APIは、リソースの消費量、リカバリ、ロード・バランシングのパフォーマンスを改善する以外に、アプリケーションに影響を及ぼしません。これらのAPIでは、JDBCメソッド、SQLまたはPL/SQLをコールすることによって、接続状態が変更されません。ローカル・トランザクションのオープン中にリクエストの開始や終了の試行を行った場合、エラーが返されます。

28.5 透過的アプリケーション・コンティニュイティのサポート

Oracle Databaseリリース18cでは、アプリケーション・コンティニュイティの機能モードである透過的アプリケーション・コンティニュイティ機能が導入されています。透過的アプリケーション・コンティニュイティは、セッションおよびトランザクションの状態を透過的に追跡および記録し、リカバリ可能な停止の後にデータベース・セッションをリカバリできるようにします。これは、安全に、アプリケーションの知識を必要とすることなく、アプリケーション・コードも変更せずに実行されます。透過性は、状態を追跡するインフラストラクチャを使用して実現されます。このインフラストラクチャは、アプリケーションがユーザー・コールを発行すると、セッション状態の使用状況を分類します。この機能により、ドライバは可能なリクエスト境界(暗黙的なリクエスト境界と呼ばれる)を検出して挿入できます。暗黙的なリクエスト境界では次のようになります。

  • オブジェクトはオープンされない

  • カーソルはドライバ文キャッシュに戻される

  • トランザクションはオープンされない

このような場合のセッション状態はリストア可能であることがわかっています。無効化イベントがあった場合、ドライバは現在の取得をクローズして新しいイベントを起動するか、取得を有効にします。サーバーへの次コールで、サーバーは検証を行い、必要に応じて、以前は明示的な境界がなかった場所に、リクエスト境界を作成します。

透過的アプリケーション・コンティニュイティを使用するには、データベース・サービス上のサーバー側サービス属性FAILOVER_TYPEAUTOに設定する必要があります。

暗黙的なリクエストのサポートは、アプリケーション・フェイルオーバーのリカバリ時間の短縮、およびアプリケーション・コンティニュイティの最適化に役立ちます。透過的アプリケーション・コンティニュイティを使用して、サーバーおよびドライバはトランザクションとセッション状態の使用状況を追跡できます。ただし、リクエスト中にサーバーのセッション状態を変更するアプリケーションの場合、この機能は注意して使用する必要があります。JDBC Thinドライバには、必要な場合に暗黙的にリクエストをオフにするoracle.jdbc.enableImplicitRequestsプロパティが用意されています。このプロパティは、システム・レベル(すべての接続に適用される)または接続レベル(特定の接続に適用される)で設定できます。デフォルトでは、このプロパティの値はtrueです。これは、暗黙的なリクエストのサポートが有効になっていることを意味します。

28.6 アプリケーション・コンティニュイティのリプレイ前の初期状態の確立

非トランザクション・セッション状態(NTSS)とは、データベース・トランザクションの外部に存在し、リカバリによって保護されていないデータベース・セッションの状態です。ステートフル・リクエストを使用するアプリケーションの場合、非トランザクション状態は再構築済セッションとして再確立されます。

リクエストの開始時のみに状態を設定するアプリケーションの場合、または事前設定済の状態で接続を使用してパフォーマンス上の利点を得るステートフル・アプリケーションの場合、次のコールバック・オプションの中からいずれかを指定します。

28.6.1 コールバックなし

このシナリオの場合、アプリケーションは各リクエスト時に独自の状態を構築します。

28.6.2 接続ラベリング

このシナリオは、ユニバーサル接続プール(UCP)およびOracle WebLogic Serverのみに適用可能です。接続に事前設定された状態を活用するようアプリケーションを変更できます。接続ラベリングAPIにより、接続の一致状況が判別され、接続が流用される際にコールバックを使用してギャップが移入されます。接続ラベリングでは再コーディングが必要になる部分もあるため、すべてのアプリケーションがこれを使用できるわけではありません。

28.6.3 接続初期化コールバック

このシナリオの場合、リプレイ・ドライバがアプリケーション・コールバックを使用して、ランタイムおよびリプレイ時にセッションの初期状態を設定します。JDBCリプレイ・ドライバは、オプションの接続の初期化コールバック・インタフェースおよびこのようなコールバックの登録と登録解除のメソッドを提供します。

接続初期化コールバックは、登録されると、リカバリ可能なエラーの後に成功した再接続ごとに実行されます。アプリケーションは、初期化アクションがフェイルオーバー前の元の接続時のものと同じであることを確認する必要があります。コールバックの起動が失敗した場合、リプレイはその接続で無効になります。

次の項で、初期化コールバックについて説明します。

28.6.3.1 初期化コールバックの作成

JDBC接続の初期化コールバックを作成するには、アプリケーションでoracle.jdbc.replay.ConnectionInitializationCallbackインタフェースを実装します。oracle.jdbc.replay.OracleDataSourceインタフェースのインスタンスごとに、1つのコールバックが許可されます。

ノート:

このコールバックは、再接続の成功後、フェイルオーバー中にのみ起動されます。

次のコードでは、単純な初期化コールバックの実装を示します。

import oracle.jdbc.replay.ConnectionInitializationCallback;
class MyConnectionInitializationCallback implements ConnectionInitializationCallback
{
    public MyConnectionInitializationCallback()  
    {
        ...
    }
    public void initialize(java.sql.Connection connection) throws SQLException
    {
        // Reset the state for the connection, if necessary (like ALTER SESSION)
        ...
    }
 }

XAデータソースを使用するアプリケーションの場合、接続初期化コールバックがXAリプレイ・データソース上で登録されます。次の両方が発生した場合は常に、コールバックが実行されます。

  • 接続が接続プールから流用されるとき。

  • リプレイXAデータソースがフェイルオーバーで新しい物理接続を取得したとき。

ノート:

接続の初期化は冪等にする必要があります。接続がすでに初期化されている場合、これを繰り返す必要はありません。これにより、アプリケーションでは、フェイルオーバー後でリプレイか開始される前にセッションの最初の開始ポイントを再確立できるようになります。コールバックの実行では、オープンしているローカル・トランザクションをコミットまたはロールバックしないで残す必要があります。これに違反すると、例外が発生します。

コールバックの起動が失敗した場合、リプレイはその接続で無効になります。たとえば、アプリケーションでは接続の設定フェーズをこのコールバックに埋め込みます。

28.6.3.2 初期化コールバックの登録

JDBCリプレイ・ドライバがoracle.jdbc.replay.OracleDataSourceインタフェースで提供する次のメソッドを使用して、接続の初期化コールバックを登録します。

registerConnectionInitializationCallback(ConnectionInitializationCallback cbk)

OracleDataSourceインタフェースのインスタンスごとに、1つのコールバックが許可されます。

XAデータソースを使用している場合、oracle.jdbc.replay.OracleXADataSourceインタフェースでregisterConnectionInitializationCallback(ConnectionInitializationCallback cbk)メソッドを使用します。

28.6.3.3 初期化コールバックの削除または登録解除

JDBCリプレイ・ドライバがoracle.jdbc.replay.OracleDataSourceインタフェースで提供する次のメソッドを使用して、接続の初期化コールバックの登録を解除します。

unregisterConnectionInitializationCallback(ConnectionInitializationCallback cbk)

XAデータソースを使用している場合、oracle.jdbc.replay.OracleXADataSourceインタフェースでunregisterConnectionInitializationCallback(ConnectionInitializationCallback cbk)メソッドを使用します。

28.6.4 FAILOVER_RESTOREの有効化について

FAILOVER_RESTOREサービス属性は、Oracle Database 12cリリース2 (12.2.0.1).で導入されました。FAILOVER_RESTORELEVEL1に設定すると、リクエストをリプレイする前の共通の初期状態に自動的にリストアされます。デフォルトでは、FAILOVER_RESTORE属性の値がNONEに設定されていますが、これは無効になっているということです。

Oracle Databaseリリース18c以降、この属性の値をAUTOに設定することもできます。また、FAILOVER_TYPE属性の値をAUTOに設定すると、FAILOVER_RESTOREは自動的にAUTOに設定されます。FAILOVER_TYPEAUTOに設定されているかぎり、FAILOVER_RESTOREの値をそれ以外に変更することはできません。FAILOVER_RESTOREAUTOに設定されている場合、共通の初期状態も設定されます。セッション状態のリストアに関するかぎり、この設定は、FAILOVER_RESTORELEVEL1に設定した場合と同じ機能を提供します。

ノート:

Oracle Databaseリリース18cで使用可能なJava用のアプリケーション・コンティニュイティの場合、次の初期状態がFAILOVER_RESTOREでサポートされています。

  • NLS_CALENDAR

  • NLS_CURRENCY

  • NLS_DATE_FORMAT

  • NLS_DATE_LANGUAGE

  • NLS_DUAL_CURRENCY

  • NLS_ISO_CURRENCY

  • NLS_LANGUAGE

  • NLS_LENGTH_SEMANTICS

  • NLS_NCHAR_CONV_EXCP

  • NLS_NUMERIC_CHARACTER

  • NLS_SORT

  • NLS_TERRITORY

  • NLS_TIME_FORMAT

  • NLS_TIME_TZ_FORMAT

  • NLS_TIMESTAMP_FORMAT

  • NLS_TIMESTAMP_TZ_FORMAT

  • TIME_ZONE (OCI, ODP.NET 12201)

  • CURRENT_SCHEMA

  • MODULE

  • ACTION

  • CLIENT_ID

  • ECONTEXT_ID

  • ECONTEXT_SEQ

  • DB_OP

  • AUTOCOMMIT状態(JavaおよびSQL*Plus)

  • CONTAINER (PDB)およびSERVICE (OCIおよびODP.NETの場合)

次に示す状態は、Thinドライバでサポートされていないため、自動リストア・オプションから除外されます。

  • NLS_COMP

  • CALL_COLLECT_TIME

  • CLIENT_INFO

多くのアプリケーションの場合、ACリプレイに必要な初期状態を自動的にリストアするには、コールバックの使用は不要で、FAILOVER_RESTOREの有効化で十分です。アプリケーションで前述のリストに記載されていない初期状態が必要な場合、または、アプリケーションで初期状態の設定の明示的な制御が適切な場合、アプリケーションでは接続ラベリングまたは初期化コールバックのいずれかのコールバックを使用する必要があります。コールバックを構成すると、初期化コールバックが同時に有効になっている場合にFAILOVER_RESTOREでリストアされた初期状態がオーバーライドされます。

28.7 Java用のアプリケーション・コンティニュイティにおける再接続の遅延について

デフォルトでは、JDBCリプレイ・ドライバは、フェイルオーバーを開始する際に、サービスが使用可能なインスタンスで進行中の作業をリカバリしようとします。これを実行するには、ドライバは最初に、実行中のインスタンスに対して適切な接続を再確立する必要があります。サービスが再配置および発行される前にデータベースまたはインスタンスを再起動する必要がある場合、再接続に時間がかかる場合があります。したがって、サービスが別のインスタンスまたはデータベースから利用可能になるまでに、フェイルオーバーを遅延させる必要があります。

再接続を管理するには、FAILOVER_RETRIESおよびFAILOVER_DELAYパラメータを使用する必要があります。これらのパラメータは計画済停止と連動して使用すると効果があります。たとえば、サービスが数分間使用不可になる可能性がある停止の場合などです。FAILOVER_DELAYおよびFAILOVER_RETRIESパラメータを設定する場合は、REPLAY_INITIAITION_TIMEOUTパラメータの値を最初に確認します。このパラメータのデフォルト値は900秒です。FAILOVER_DELAYパラメータの値が高い場合、リプレイが取り消されることがあります。

パラメータ名 使用可能な値 デフォルト値

FAILOVER_RETRIES

正の整数ゼロ以上

30

FAILOVER_DELAY

秒数

10

28.7.1 Java用のアプリケーション・コンティニュイティに関する構成例

次の項では、サービスの作成と変更の構成例について説明します。

28.7.1.1 Oracle RACでのサービスの作成

Oracle RACまたはOracle RAC Oneを使用している場合、SRVCTLコマンドを使用して次の方法でサービスを作成および変更します。

透過的アプリケーション・コンティニュイティの場合

次のように、透過的アプリケーション・コンティニュイティを使用するサービスを作成できます。

ポリシー管理データベースの場合:

$ srvctl add service -db codedb -service GOLD -serverpool ora.Srvpool -clbgoal SHORT -rlbgoal SERVICE_TIME -failover_restore AUTO -failoverretry 30 
-failoverdelay 10 -commit_outcome TRUE -failovertype AUTO -replay_init_time 1800 -retention 86400  -notification TRUE

管理者管理データベースの場合:

$ srvctl add service -db codedb -service GOLD -preferred serv1 -available serv2 -clbgoal SHORT -rlbgoal SERVICE_TIME -failover_restore AUTO 
-failoverretry 30 -failoverdelay 10 -commit_outcome TRUE -failovertype AUTO -replay_init_time 1800 -retention 86400 -notification TRUE

手動によるアプリケーション・コンティニュイティの場合

次のように、手動によるアプリケーション・コンティニュイティを使用するサービスを作成できます。

ポリシー管理データベースの場合:

$ srvctl add service -db codedb -service GOLD -serverpool ora.Srvpool -clbgoal SHORT -rlbgoal SERVICE_TIME -failover_restore LEVEL1 -failoverretry 30 
-failoverdelay 10 -commit_outcome TRUE -failovertype TRANSACTION -replay_init_time 1800 -retention 86400 -notification TRUE

管理者管理データベースの場合:

$ srvctl add service -db codedb -service GOLD -preferred serv1 -available serv2 -clbgoal SHORT -rlbgoal SERVICE_TIME -failover_restore LEVEL1 
-failoverretry 30 -failoverdelay 10 -commit_outcome TRUE -failovertype TRANSACTION -replay_init_time 1800 -retention 86400 -notification TRUE
28.7.1.2 単一インスタンス・データベースでのサービスの変更

単一インスタンス・データベースを使用している場合、DBMS_SERVICEパッケージを使用して次の方法でサービスを変更します。

declare
params dbms_service.svc_parameter_array;
begin
params('FAILOVER_TYPE'):='TRANSACTION';
params('REPLAY_INITIATION_TIMEOUT'):=1800;
params('RETENTION_TIMEOUT'):=604800;
params('FAILOVER_DELAY'):=10;
params('FAILOVER_RETRIES'):=30;
params('commit_outcome'):='true';
params('aq_ha_notifications'):='true';
dbms_service.modify_service('[your service]',params);
end;
/

28.8 Java用のアプリケーション・コンティニュイティにおける可変値の保持について

可変オブジェクトとは、変数、関数からの戻り値、またはコールされるたびに異なる値を戻す構造体です。たとえば、Sequence.NextValSYSDATESYSTIMESTAMPおよびSYS_GUIDです。リプレイ時に名前付きの関数の結果を保持するには、DBAは関数を起動するユーザーにKEEP権限を付与する必要があります。このセキュリティの制限は、ユーザーが所有していないコードに対してリプレイが関数の結果の保存およびリストアを行うことが有効であることを保証するために強制されています。

28.8.1 インタフェースの付与または取消し

次のように標準的なGRANTおよびREVOKEインタフェースを使用して、可変値を使用できます。

28.8.1.1 DateおよびSYS_GUID構文

DATE_TIMEおよびSYS_GUID構文は次のとおりです。

GRANT [KEEP DATE TIME|SYSGUID]..[to USER}
REVOKE [KEEP DATE TIME | KEEP SYSGUID] … [from USER]

たとえば、元の日付をEBSで標準的に使用する場合:

Grant KEEP DATE TIME,  KEEP SYSGUID  to [custom user];
Grant KEEP DATE TIME,  KEEP SYSGUID  to [apps user];
28.8.1.2 Sequence構文

Sequence構文には次のタイプがあります。

所有済Sequence構文

ALTER SEQUENCE [sequence object] [KEEP|NOKEEP];

このコマンドは、リプレイ後にキーが一致するように、リプレイ用にsequence.nextvalの元の値を保持します。ほとんどのアプリケーションはリプレイ時にシーケンスの値を保持する必要があります。ALTER SYNTAXは所有済シーケンス専用です。

その他のSequence構文

GRANT KEEP SEQUENCE..[to USER] on [sequence object];
REVOKE  KEEP SEQUENCE … [from USER]  on [sequence object];

たとえば、元のシーケンス値をEBSで標準的に使用する場合、次のコマンドを使用します。

Grant KEEP SEQUENCE  to [apps user] on [sequence object]; 
Grant KEEP SEQUENCE  to [custom user] on [sequence object];
28.8.1.3 GRANT ALL文

GRANT ALL文では、KEEP権限をユーザーのすべてのオブジェクトに付与します。ただし、ここでは可変値は除外されます。つまり、可変値には明示的な付与が必要です。

28.8.1.4 可変値における付与のルール

可変オブジェクトに権限を付与する場合、次のルールに従います。

  • 可変値に対してKEEP権限が付与されているユーザーの場合、SYS_GUIDSYSDATEおよびSYSTIMESTAMP関数がコールされたとき、オブジェクトは可変アクセスを継承します。

  • シーケンス・オブジェクトの可変値に対するKEEP権限が取り消された場合、このオブジェクトを使用するSQLまたはPL/SQLブロックは、このシーケンスに対して可変コレクションまたはアプリケーションを許可しません。

  • 付与された権限がランタイムとフェイルオーバーの間に取り消されると、収集された可変値はリプレイに適用されません。

  • 新しい権限が実行時とフェイルオーバー間で付与された場合、可変値は収集されず、これらの値はリプレイに適用されません。

28.9 アプリケーション・コンティニュイティの統計

JDBCリプレイ・ドライバでは、アプリケーション・コンティニュイティを使用したアプリケーションの次の統計をサポートしています。

  • リクエストの合計数

  • 完了したリクエストの合計数

  • 合計コール数

  • 保護されたコールの合計数

  • 停止の影響を受けるコールの合計数

  • リプレイをトリガーするコールの合計数

  • リプレイ中に停止の影響を受けるコールの合計数

  • 成功したリプレイの合計数

  • 失敗したリプレイの合計数

  • 無効になったリプレイの合計数

  • リプレイ試行の合計数

これらのすべてのメトリックは、接続単位でも接続全体でも使用できます。これらの統計を取得するには、次のメソッドを使用できます。

  • getReplayStatistics(StatisticsReportType)

    oracle.jdbc.replay.ReplayableConnection.getReplayStatistics(StatisticsReportType)メソッドを使用して、スナップショット統計を取得します。このメソッドの引数は、同じReplayableConnectionインタフェースでも定義済の列挙型です。接続全体の統計を取得するには、アプリケーションのメイン・ロジックの後にこのメソッドをコールすることをお薦めします。アプリケーションでは、オープンしているoracle.jdbc.replay.ReplayableConnectionを使用することも、同じデータソースに対して新規接続をオープンすることもできます。これは、UCPとWLSの両方のデータソースを使用しているアプリケーション、およびリプレイ・データソースを直接使用しているアプリケーションに適用されます。

  • getReplayStatistics()

    oracle.jdbc.replay.OracleDataSource.getReplayStatistics()メソッドを使用して接続全体の統計を取得します。これは、リプレイ・データソースを直接使用しているアプリケーションにのみ適用されます。

両方のメソッドは、個々のリプレイ・メトリックを取得できる位置からoracle.jdbc.replay.ReplayStatisticsオブジェクトを戻します。次にReplayStatisticsオブジェクトを文字列として出力するサンプル出力を示します。

AC Statistics:
===============================================
TotalRequests = 1
TotalCompletedRequests = 1
TotalCalls = 19
TotalProtectedCalls = 19
===============================================
TotalCallsAffectedByOutages = 3
TotalCallsTriggeringReplay = 3
TotalCallsAffectedByOutagesDuringReplay = 0
===============================================
SuccessfulReplayCount = 3
FailedReplayCount = 0
ReplayDisablingCount = 0
TotalReplayAttempts = 3
===============================================

接続単位またはすべての接続の累積したリプレイ統計をクリアする場合、次のメソッドを使用できます。

  • oracle.jdbc.replay.ReplayableConnection.clearReplayStatistics(ReplayableConnection.StatisticsReportType reportType)

  • oracle.jdbc.replay.OracleDataSource.clearReplayStatistics()

ノート:

すべての統計には、直近のクリア以降の更新のみが反映されています。

28.10 Java用のアプリケーション・コンティニュイティにおけるリプレイの無効化について

28.10.1 リプレイを無効にする方法

アプリケーション・モジュールがリプレイに不適切な設計を使用する場合、リプレイの無効化APIがリプレイごとにリプレイを無効にします。リプレイの無効化は、oracle.jdbc.replay.ReplayableConnectionインタフェースのdisableReplayメソッドを使用して、コールバックまたはメイン・コードに追加できます。次に例を示します。

if (connection instanceof oracle.jdbc.replay.ReplayableConnection)
{ 
    (( oracle.jdbc.replay.ReplayableConnection)connection).disableReplay(); 
    
}

リプレイを無効にしても、JDBCメソッド、SQLまたはPL/SQLの再実行によって接続状態が変更されません。リプレイの無効化APIを使用してリプレイを無効にした場合、リクエストが終了するまで記録もリプレイも無効になります。リプレイされたリクエストで時間のギャップのあるデータベース・セッションを再確立しても無効であるため、リプレイを有効にするAPIはありません。これにより、必要なコールのすべての履歴が記録された場合にのみ、リプレイが実行されます。

28.10.2 リプレイを無効にするタイミング

デフォルトでは、JDBCリプレイ・ドライバは次のリカバリ可能なエラーをリプレイします。リプレイの無効化APIは、データベース・セッションを失ってリカバリできないアプリケーション・モジュールのエントリ・ポイントで使用できます。たとえば、アプリケーションがUTL_SMTPパッケージを使用し、メッセージを繰り返す必要がない場合、disableReplay APIは無効にする必要があるリクエストのみに影響します。他のすべてのリクエストは引き続きリプレイされます。

リプレイに対してアプリケーションを構成する前に検討する必要があるシナリオは、次のとおりです。

28.10.2.1 アプリケーションが繰り返す必要のない外部PL/SQLアクションをコールする場合

リプレイ中に、自律型トランザクションと外部PL/SQLのコールが、メイン・トランザクションとは別の悪影響を及ぼす可能性があります。リプレイしないように指定しないと、これらの悪影響がリプレイされ、結果が持続します。これらの悪影響には、外部テーブルへの書込み、電子メールの送信、PL/SQLまたはJavaからのセッションの分岐化、ファイルの転送、外部URLへのアクセスなどがあります。たとえば、PL/SQLメッセージを送信する場合、コミットせずに作業中にその作業を離れ、セッションがタイムアウトしたとします。そこで、Ctrl+Cコマンドを発行した場合、フォアグラウンドのコンポーネントが失敗します。作業を再発行したとき、この悪影響も繰り返される可能性があります。

関連項目:

発生する可能性のあるアプリケーション・コンティニュイティの悪影響の詳細は、『Oracle Real Application Clusters管理およびデプロイメント・ガイド』を参照してください

外部アクションのリプレイを有効にするかどうかを意識的に決定する必要があります。たとえば、このような決定が重要である、次の状況を考慮します。

  • UTL_HTTPパッケージを使用してSOAコールを発行する。

  • UTL_SMTPパッケージを使用してメッセージを送信する。

  • UTL_URLパッケージを使用してWebサイトにアクセスする。

外部アクションがリプレイしないようにする場合、disableReplay APIを使用します。

28.10.2.2 アプリケーションが独立セッションを同期化する場合

コミット、ロールバックまたはセッションの喪失まで維持される揮発エンティティを使用して、アプリケーションが独立セッションを同期する場合、リプレイ用にアプリケーションを構成できます。このような場合、アプリケーションは、データベースのロックなどのリソースを使用して相互に依存している、いくつかのデータソースに接続した複数のセッションを同期します。アプリケーションでこれらのセッションのみがシリアライズされ、いずれかのセッションが失敗する可能性があることが認識されている場合、このような同期が有効なことがあります。ただし、1つのデータソースによって保持されているロックまたは他の高揮発リソースが、他の接続から同一または別個のデータソースのデータに対する排他的アクセスを実現することをアプリケーションが想定している場合、この想定はリプレイ時に否定される可能性があります。

リプレイ中、ドライバは、ロックまたは他の高揮発リソースを保持している1つのセッションにこれらのセッションが依存していることを認識していません。また、リソース(セマフォ、デバイスまたはソケットなどの)を使用するパイプ、バッファ・キュー、ストアド・プロシージャを使用して、失敗によって失われる同期を実行することもできます。

ノート:

DBMS_LOCKは、制限されたバージョンではリプレイしません。

28.10.2.3 アプリケーションが実行ロジックの中間層で時間を使用する場合

この場合、アプリケーションは実行ロジックに従って中間層の実時間を使用します。JDBCリプレイ・ドライバは、中間層の時刻ロジックは繰り返さず、このロジックの一部として実行されるデータベース・コールを使用します。たとえば、中間層の時間を使用するアプリケーションが明示的にこれを使用していなければ、時間T1で実行された文が時間T2で再実行されていないと想定することがあります。

28.10.2.4 アプリケーションでROWIDが変更されないことが想定される場合

アプリケーションがROWIDをキャッシュする場合、データベースが変更されているためにROWIDへのアクセスが無効になることがあります。ROWIDが表内の一意の行を特定しても、次のような状況ではROWIDの値が変更されることがあります。

  • 基礎となる表が再編成された場合

  • 表に索引が作成された場合

  • 基礎となる表がパーティション化された場合

  • 基礎となる表が移行された場合

  • 基礎となる表がEXP/IMP/DULを使用してエクスポートおよびインポートされた場合

  • 基礎となる表がGolden Gateまたはロジカル・スタンバイまたは他のレプリケーション・テクノロジを使用して再構築された場合

  • 基礎となる表のデータベースがフラッシュバックされたかリストアされた場合

アプリケーションがROWIDを将来的に使用するために保存することは、対応する行が存在しないかまったく異なるデータを含んでいることがあるため、適切ではありません。

28.10.2.5 アプリケーションで悪影響が一度発生することが想定される場合

この場合、リプレイ中にリプレイされる処理は、次のとおりです。

  • 自律型トランザクション

  • メイン・トランザクションの悪影響と別のバック・チャネルのオープン

メイン・トランザクションと別のバック・チャネルの例には、外部表への書込み、電子メールの送信、PL/SQLまたはJavaからのセッションの分岐化、出力ファイルへの書込み、ファイルの転送および例外ファイルへの書込みがあります。これらのアクションのいずれかは、リプレイがないときも悪影響が持続します。バック・チャネルに、引き続き結果が残っていることがあります。たとえば、ユーザーがトランザクションをコミットしないままにしてセッションがタイムアウトした場合、Ctrl+Cを押すと、フォアグラウンドのコンポーネントが失敗します。ユーザーが作業を再発行した場合、悪影響が繰り返されることがあります。

28.10.2.6 アプリケーションでロケーション値が変更されないことが想定される場合

SYSCONTEXTオプションは、各国語サポート(NLS)設定、ISDBACLIENT_IDENTIFIERMODULEおよびACTIONなどのロケーション非依存セットと、物理ロケータを使用するロケーション依存セットで構成されています。通常、アプリケーションではテスト環境を除いて、物理識別子を使用しません。物理ロケータがメインライン・コードで使用されている場合、リプレイによって不一致が検出され、拒否されます。ただし、コールバックで物理的なロケータを使用することは適切です。

select 
    sys_context('USERENV','DB_NAME') 
    ,sys_context('USERENV','HOST') 
    ,sys_context('USERENV','INSTANCE') 
    ,sys_context('USERENV','IP_ADDRESS') 
    ,sys_context('USERENV','ISDBA')  
    ,sys_context('USERENV','SESSIONID') 
    ,sys_context('USERENV','TERMINAL') 
    ,sys_context('USERENV',ID') 
from dual

28.10.3 診断とトレース

JDBCリプレイ・ドライバは、標準のJDKロギングをサポートしています。ロギングは、Javaのコマンドラインの-Djava.util.logging.config.file=<file>オプションを使用して有効にします。ログ・レベルは、ログ構成ファイルのoracle.jdbc.internal.replay.level属性で制御されます。次に例を示します。

oracle.jdbc.internal.replay.level = FINER|FINEST

ここで、FINERは外部APIを作成し、FINESTは大量のトレースを作成します。管理されている場合にのみ、FINESTを使用する必要があります。

java.util.logging.XMLFormatterクラスを使用してログ・レコードをフォーマットする場合、ログは読み取りやすくなりますが、大きくなります。UCPまたはWebLogic Serverで有効になっているFANでリプレイを使用している場合、FANを処理するロギングも有効にする必要があります。

28.10.3.1 リプレイ・トレースのコンソールへの書込み

次に、ロギング構成用の構成ファイルの例を示します。

oracle.jdbc.internal.replay.level = FINER
handlers = java.util.logging.ConsoleHandler
java.util.logging.ConsoleHandler.level = ALL
java.util.logging.ConsoleHandler.formatter = java.util.logging.XMLFormatter
28.10.3.2 リプレイ・トレースのファイルへの書込み

次に、ロギング構成用のpropertiesファイルの例を示します。

oracle.jdbc.internal.replay.level = FINEST
# Output File Format (size, number and style)
# count: Number of output files to cycle through, by appending an integer to the base file name:
# limit: Limiting size of output file in bytes
handlers = java.util.logging.FileHandler
java.util.logging.FileHandler.pattern = [file location]/replay_%U.trc
java.util.logging.FileHandler.limit = 500000000
java.util.logging.FileHandler.count = 1000
java.util.logging.FileHandler.formatter = java.util.logging.XMLFormatter


脚注の凡例

脚注1:

ログオン・ストームとは、クライアントの接続リクエストの数が突然増加することです。