ヘッダーをスキップ
Oracle® Database JDBC開発者ガイド
12cリリース1 (12.1)
B71308-02
  目次へ移動
目次
索引へ移動
索引

前
 
次
 

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

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


注意:

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

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


関連項目:

  • アプリケーション・コンティニュイティの詳細は、『Oracle Database開発ガイド』を参照してください。

  • トランザクション・ガードの詳細は、『Oracle Database開発ガイド』を参照してください。

  • 「Java用のトランザクション・ガード」


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

Java用のアプリケーション・コンティニュイティのためのOracle JDBCの構成

oracle.jdbc.replay.OracleDataSourceImplまたはoracle.jdbc.replay.OracleConnectionPoolDataSourceImplのどちらかのデータソースを使用してJDBC接続を取得する必要があります。これは、新しいOracle JDBCデータソースで、oracle.jdbc.pool.OracleDataSourceなどの既存の非XAデータソースと同様に機能します。双方ともスタンドアロン方式で使用するか、ユニバーサル接続プール(UCP)またはOracle WebLogic Server接続プールなどの接続プール用コネクション・ファクトリとして構成することができます。

次のコード・スニペットは、スタンドアロンJDBCアプリケーションでの使用方法を示しています。

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
......

関連項目:

Oracle JDBCデータソースの詳細は、「データソースおよびURL」を参照してください

接続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_COUNTCONNECT_TIMEOUTおよびTRANSPORT_CONNECT_TIMEOUTパラメータを設定します。Oracle Databaseリリース11.2.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=3)
     (RETRY_COUNT=20)(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=3)
    (CONNECT_TIMEOUT=60)(RETRY_COUNT=20)(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 
    

    関連項目:

    • ローカル・ネーミング・パラメータの詳細は、『Oracle Database Net Servicesリファレンス』

    • 『Oracle Real Application Clusters管理およびデプロイメント・ガイド』


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パッケージを使用します。

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

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

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

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

    • リプレイごとの接続の再試行回数を指定する場合: FAILOVER_RETRIES = 30

    • 接続の再試行間の遅延時間(秒)を指定する場合: FAILOVER_DELAY = 10

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

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

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

    • 有効化と無効化

    • Oracle RACへの再配置

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


関連項目:

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

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

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


注意:

データベース常駐接続プール(DRCP)はアプリケーション・コンティニュイティとともに動作しないため、DRCPから接続を流用できません。DRCPの詳細は、第23章「データベース常駐接続プーリング」を参照してください。

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

アプリケーションがこれらのOracleの接続プールから、またはoracle.jdbc.replay.OracleConnectionPoolDataSourceImplデータソースから接続を使用する場合、リクエスト境界を識別するために、アプリケーションを変更する必要はありません。ただし、接続プールが動作するには、必要な場合にアプリケーションが接続を取得し、使用していない場合に接続を解放する必要があります。これによって、リクエスト境界をより正しく見積もり、透過的に提供できます。

Oracle接続プールから接続の流用と返却を行わないアプリケーションは、明示的にリクエスト境界をマークする必要があります。たとえば、アプリケーションがカスタムのJDBCプールを使用している場合、チェックアウト時にbeginRequestメソッドを呼び出し、チェックイン時にendRequestメソッドをコールする必要があります。これらのメソッドは、接続プールを使用せずに、スタンドアロンのJDBCアプリケーション用に使用することもできます。

APIは、リソースの消費量、リカバリ、ロード・バランシングのパフォーマンスを改善する以外に、アプリケーションに影響を及ぼしません。これらのAPIでは、JDBCメソッド、SQLまたはPL/SQLをコールすることによって、接続状態が変更されません。ローカル・トランザクションのオープン中にリクエストの開始や終了の試行を行った場合、エラーが返されます。

アプリケーション・コンティニュイティにおける接続の初期化コールバックの登録(オプション)

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

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

コールバックなし

このシナリオでは、アプリケーションは各リクエスト中に専用の状態を設定します。

接続ラベリング

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


関連項目:

『Oracle Universal Connection Pool for JDBC開発者ガイド』

接続初期化コールバック

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

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

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

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

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)
        ...
    }
 }

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

JDBCリプレイ・ドライバには、接続初期化コールバックを登録するために、oracle.jdbc.replay.OracleDataSourceインタフェースのregisterConnectionInitializationCallback(ConnectionInitializationCallback cbk)メソッドが用意されています。OracleDataSourceインタフェースのインスタンスごとに、1つのコールバックが許可されます。

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

JDBCリプレイ・ドライバには、接続初期化コールバックを登録解除するために、oracle.jdbc.replay.OracleDataSourceインタフェースのunregisterConnectionInitializationCallback(ConnectionInitializationCallback cbk)メソッドが用意されています。

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

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

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

パラメータ名 使用可能な値 デフォルト値
FAILOVER_RETRIES 0以上の正の整数 30
FAILOVER_DELAY 秒数 10

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

Oracle RACでのサービスの作成

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

ポリシー管理型の環境の場合

srvctl add service -d codedb -s GOLD -g Srvpool -j SHORT -B SERVICE_TIME –z 30 –w 10 -commit_outcome
 TRUE -e TRANSACTION -replay_init_time 1800 -retention 86400 -notification TRUE

管理者管理型の環境の場合

srvctl add service -d codedb -s GOLD -r serv1 -a serv2  -j SHORT -B SERVICE_TIME –z 30 –w 10 -commit_outcome
 TRUE -e TRANSACTION -replay_init_time 1800 -retention 86400 -notification TRUE

単一インスタンス・データベースにおけるサービスの変更

単一インスタンス・データベースを使用している場合、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;
/

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

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


関連項目:

『Oracle Database開発ガイド』

GrantおよびRevokeインタフェース

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

DateおよびSYS_GUID構文

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

GRANT [KEEP DATE_TIME | KEEP SYS_GUID].. [to  USER]
REVOKE [KEEP DATE_TIME | KEEP SYS_GUID] … [from USER]

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

Grant KEEP DATE_TIME,  KEEP SYS_GUID  to [custom user];
Grant KEEP DATE_TIME,  KEEP SYS_GUID  to [apps user];

Sequence構文

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

所有済Sequence構文

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

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

その他のSequence構文

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

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

Grant KEEP SEQUENCES  to [apps user] on [sequence object]; 
Grant KEEP SEQUENCES  to [custom user] on [sequence object];

GRANT ALL文

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

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

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

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

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

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

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

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

この項では、次の概念について説明します。

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

アプリケーション・モジュールがリプレイに不適切な設計を使用する場合、リプレイの無効化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はありません。これにより、必要なコールのすべての履歴が記録された場合にのみ、リプレイが実行されます。

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

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

リプレイ用にアプリケーションを構成する前に考慮するシナリオは次のとおりです。

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

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


関連項目:

発生する可能性のあるアプリケーション・コンティニュイティの悪影響の詳細は、『Oracle Database開発ガイド』を参照してください。

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

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

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

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

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

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

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

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


注意:

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

診断とトレース

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を処理するロギングも有効にする必要があります。


関連項目:

『Oracle Universal Connection Pool for JDBC開発者ガイド』

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

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

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

例: リプレイ・トレースのファイルへの書込み

次に、ロギング構成用の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:  ログオン・ストームとは、クライアントの接続リクエストの数が突然増加することです。