Oracle® Fusion Middleware Oracle WebLogic Server JDBCデータ・ソースの構成と管理の構成と管理 11gリリース1 (10.3.6) B60997-10 |
|
前 |
次 |
この章では、Oracleドライバとデータベースを使用する場合にデータ・ソースとドライバのパフォーマンスを向上させる詳細構成オプションを提供します。オプションには、プロキシ認証、接続での資格証明の設定、接続収集、接続のラベル付けなどがあります。
WebLogic Serverには、次のようなOracleドライバの使用時に向上したデータ・ソース・パフォーマンスを提供するいくつかの属性が用意されています。
OracleでJavaNet Fastpathの有効化: Oracle JDBC JavaNet Fastpathを有効化して、データ・コピーと断片化を削減します。
OracleでUTF8変換の最適化: Oracle JDBC UTF-8変換の最適化オプションを有効化します。
環境でこれらの属性をサポートする場合、Oracle WebLogic Server管理コンソール・ヘルプの「Oracleパラメータの構成」を参照してください。
プロキシ認証により、1つのJDBC接続が、Oracleデータベースへの他のJDBC接続のプロキシとして機能できます。クライアントがプロキシ・ユーザーとしてアプリケーション・サーバーを通じてデータベースに接続できるようにWebLogicデータ・ソースを構成できます。クライアントはアプリケーション・サーバーで認証され、アプリケーション・サーバーはOracleデータベースで認証されます。これにより、クライアントのユーザー名を、データベースとの接続で保持できます。
Oracleデータベースへのプロキシ認証を構成するには、次の手順を使用します。
まだ実行していない場合、必要なWebLogic Serverおよびデータベース・ユーザーを作成します。
Oracleデータベースで、CONNECT THROUGH
権限を用意します。
次に例を示します。
SQL> ALTER USER wlsuser
GRANT CONNECT THROUGH dbuser
;
wlsuser
はWebLogic Serverユーザーで、dbuser
はOracleデータベース・ユーザーです。
WebLogic Serverインスタンス:
汎用またはGridLinkデータ・ソースを作成し、ユーザーをdbuser
の値に設定します。
wlsuser
の値をdbuser
の値にマップします。Oracle WebLogic Server管理コンソール・ヘルプのJDBCデータ・ソースの資格証明マッピングの構成に関する項を参照してください。
データソースを再デプロイします。
wlsuser
の値を使用して、WebLogic Serverインスタンスにログオンします。
「プロキシ認証」を有効化します。Oracle WebLogic Server管理コンソール・ヘルプの「Oracleパラメータの構成」を参照してください。
プールに対し接続リクエストが実行されるたびに、アプリケーションで認証されたユーザーの接続でプロキシ・セッションがオープンします。接続がプールに戻されると、プロキシ・セッションはクローズされます。
注意: プロキシ・セッションをオープンするか、またはクローズします。
これらの動作は、インスタンス間で接続を共有するアプリケーションに影響を与える場合があり、接続に関連する一部の状態が予期されます。 |
WebLogicデータ・ソースを構成して、Oracleデータベースの接続時にデータベース資格証明を設定する接続が可能です。構成された場合、getConnection(username, password)
を使用して作成された接続に対してプロキシ・セッションがオープンし、データベース・ユーザーおよびパスワードを指定します。これにより、多数のユーザーを認証する単純な軽量メカニズムが用意され、各データベース・ユーザーの資格証明マッピング・エントリが不要になります。
次の手順を使用して、Oracleデータベースへの接続で設定されたデータベース資格証明のプロキシ認証を構成します。
必要なデータベース・ユーザーを作成していない場合は作成します。
Oracleデータベースで、CONNECT THROUGH
権限を用意します。
次に例を示します。
SQL> ALTER USER connectionuser
GRANT CONNECT THROUGH dbuser
;
ここで、connectionuser
は認証を受けるアプリケーション・ユーザーの名前で、dbuser
はOracleデータベース・ユーザーです。
WebLogic Serverインスタンスで、汎用またはGridLinkデータ・ソースを作成し、ユーザーをdbuser
の値に設定します。
「データベース資格証明の使用」を有効化します。Oracle WebLogic Server管理コンソール・ヘルプの「Oracleパラメータの構成」を参照してください。
プールに対し接続リクエストが実行されるたびに、アプリケーションで認証されたユーザーの接続でプロキシ・セッションがオープンします。接続がプールに戻されると、プロキシ・セッションはクローズされます。
注意: プロキシ・セッションをオープンするか、またはクローズします。
これらの動作は、インスタンス間で接続を共有するアプリケーションに影響を与える場合があり、接続に関連する一部の状態が予期されます。 |
getConnection(username, password)
を使用して接続をオープンします。
注意: 「データベース資格証明の使用」が有効化されておらず、 |
トランザクションに関与する接続でのデータベース資格証明を設定する場合、次を考慮してください。
グローバル・トランザクションで非XA LLRまたは1PC (JTSドライバ)が構成されたデータ・ソースでgetConnection(username, password)
を使用すると、指定されたusername
/password
の値に関係なく、トランザクション内で取得された最初の接続が、後続のgetConnection()
リクエストで返されます。LLRまたは1PCを使用する場合のすべてのユーザーの接続で接続を共有する必要があるため、最初のgetConnection()
リクエストからプロキシ・ユーザー・セッション情報を使用する必要があります。
XAデータ・ソースの場合、接続が指定されたJVMにトランザクション・コンテキストとともに保存される可能性があり、後続のgetConnection()
リクエストが以前のgetConnection()
リクエストのプロキシ・ユーザーの接続を返す可能性があります。グローバル・トランザクションでこの機能を使用する場合、単一データベースusername
を指定することをお薦めします。
データ・ソースが指定された数の使用可能な接続に達した場合に解放する予約された接続数を指定できます。収集は、指定された数の接続をプール内で常に使用可能にするのに役立ち、接続初期化を最小限に抑えることでパフォーマンスを向上させます。
接続収集は、特にアプリケーションで接続ハンドルをキャッシュする場合に便利です。通常、キャッシングはパフォーマンス上の理由から実行されます。これは、キャッシングにより、接続がトランザクションに参加するために必要となる状態の初期化が最小限になるためです。たとえば、接続はデータ・ソースから予約され、必要なセッション状態で初期化された後、コンテキスト・オブジェクト内に保持されます。この方法で接続を保持することが、接続プールに使用可能な接続がなくなる原因になる可能性があります。接続収集により、予約された接続が適切に回収され、接続を再使用できるようになります。
アプリケーションで接続収集を使用するには、次の手順を実行します。
データ・ソース構成の「接続収集トリガー数」
属性を使用して、接続収集をトリガーするためのしきい値を有効にし、このしきい値を指定します。たとえば、「接続収集トリガー数」
が10に設定されている場合、接続収集が有効化され、使用可能な接続数が10まで減少すると、データ・ソースにより予約されている接続の収集が開始されます。値の-1では、接続収集は無効化されます。
接続収集がトリガーされると、「接続収集最大数」
により、プールに返却できる予約された接続の数が指定されます。実際に収集される接続の数は、1から「接続収集最大数」
の範囲となります。
Oracle WebLogic Server管理コンソール・ヘルプの接続プールに対する接続収集の構成に関する項を参照してください。
接続収集が有効化されると、すべての接続が収集可能になります。接続を収集可能にしない場合、引数値としてfalse
を指定してoracle.ucp.jdbc.HarvestableConnection
インタフェースのsetConnectionHarvestable(
boolean
)
メソッドをコールすることで、その接続を収集不可として明示的にマークする必要があります。
たとえば、トランザクション内でトランザクションが使用される場合に収集されないようにするには、次の文を使用します。
. . . Connection conn = datasource.getConnection(); ((HarvestableConnection) conn).setConnectionHarvestable(false); . . .
トランザクションが完了した後、setConnectionHarvestable(true)
を設定することで、接続を収集可能としてマークできます。これにより、必要な場合に接続を収集できます。isConnectionHarvestable()
をコールすることで、接続の収集可能状態を確認できます。
接続が収集されると、コールバックが登録されている場合にはアプリケーション・コールバックが実行され、接続がクリーンアップされます。接続ごとに固有のコールバックを生成する必要があります。通常、接続は接続オブジェクトを使用して初期化する必要があります。次に例を示します。
import java.sql.Connection; . . . public myHarvestingCallback implements ConnectionHarvestingCallback { private Connection conn; mycallback(Connection conn) { this.conn = conn; } public boolean cleanup() { try { conn.close(); } catch (Exception ignore) { return false; } return true; } } . . . Connection conn = ds.getConnection(); try { (HarvestableConnection)conn).registerConnectionHarvestingCallback( new myHarvestingCallback(conn)); (HarvestableConnection)conn).setConnectionHarvestable(true); } catch (Exception exception) { // This can't be from registration – setConnectionHarvestable must have failed. // That most likely means that the connection has already been harvested. // Do whatever logic is necessary to clean up here and start over. throw new Exception(”Need to get a new connection”); } . . .
注意: 次の点を考慮してください。
|
多くの場合、アプリケーションは、接続プールから取得した接続を使用する前に初期化します。初期化は一様ではなく、アプリケーション・コード内でメソッド・コールを必要とする単純な状態の再初期化や、ネットワーク上でのラウンドトリップを必要とするデータベース操作などがあります。このような初期化のコストは非常に高い場合があります。
接続のラベル付けを使用すると、アプリケーションが接続に任意の名前/値のペアを付けることができます。アプリケーションは、必要なラベルが付いた接続を接続プールにリクエストできます。特定のラベルと特定の接続状態を関連付けることで、すでに初期化されている接続をプールから取得し、再初期化の時間とコストを回避できます。接続ラベリング機能は、ユーザー定義キーまたは値に意味を与えません。ユーザー定義キーおよび値の意味は、アプリケーションでのみ定義されます。
接続ラベリングの例には、ロール、NLS言語設定、トランザクション分離レベル、ストアド・プロシージャ・コール、またはリソースによる処理の実行の前に接続上で必要となるその他のコストのかかる状態の初期化があります。
接続ラベリングは、アプリケーション・ドリブンであり、次を必要とします。
oracle.ucp.jdbc.LabelableConnection
インタフェースは、接続ラベルの適用および削除と、接続に設定されているラベルの取得に使用されます。
oracle.ucp.ConnectionLabelingCallback
インタフェースは、リクエストされたラベルが付いた接続がすでに存在するかどうかを判断するラベリング・コールバックの作成に使用されます。接続が存在しない場合、このインタフェースを使用して、現行の接続を必要に応じて構成できます。
トランザクション後に接続を維持するためにデータ・ソースを構成します。Oracle WebLogic Server管理コンソール・ヘルプの「JDBCデータ・ソース: 構成: トランザクション」を参照してください。
ラベリング・コールバックは、接続プールでラベル付けされた接続を選択する方法を定義するために使用され、アプリケーションに戻す前に、選択された接続の構成ができます。接続ラベリング機能を使用するアプリケーションは、コールバックを実装する必要があります。
ラベリング・コールバックは、ラベル付けされた接続がリクエストされていながら、リクエストされたラベルと一致する接続がプールにない場合に使用されます。コールバックは、リクエストされたラベルと一致するように再構成するために必要となる作業量が最も少ない接続を特定した後、アプリケーションに戻す前に接続のラベルを更新できるようにします。
注意: 接続ラベリングは、RMIを使用するクライアント・アプリケーションではサポートされません。『Oracle WebLogic Server JDBCのプログラミング』のWebLogic RMIドライバの使用(非推奨)に関する項を参照してください。 |
ラベリング・コールバックを作成するには、アプリケーションにoracle.ucp.ConnectionLabelingCallback
インタフェースを実装します。コールバックは、接続プールごとに1つ作成されます。このインタフェースは、次に示す2つのメソッドを備えています。
public int cost(Properties requestedLabels, Properties currentLabels);
public boolean configure(Properties requestedLabels, Connection conn);
接続プール内で使用可能な各接続に対して繰り返します。接続ごとにcost
メソッドをコールします。cost
メソッドの結果は、接続を必要な状態に再構成するために必要なコストの見積りを表す整数値です。値が大きいほど、接続の再構成にはコストがかかります。接続プールは、常に最も低いコスト値の接続を戻します。アルゴリズムは次のとおりです。
costメソッドがある接続について0を戻した場合、その接続が適合となります(これは、requestedLabels
とcurrentLabels
が同等ということを示しません)。接続プールは、検出された接続に対してconfigureをコールせず、単に接続を戻します。
costメソッドが0以外の値(負または正の整数)を戻した場合、コスト値が0の接続を検出するか、使用可能な接続がなくなるまで繰り返します。
すべての使用可能な接続に対して繰り返して、接続の最低コストがInteger.MAX_VALUE
(デフォルトでは2147483647)となった場合、プール内に接続リクエストを満たす接続はありません。新しい接続を作成し、それに対しconfigure
メソッドをコールし、この新しい接続を戻します。プールが最大プール・サイズに達している(新しい接続を作成できない)場合は、SQL例外をスローするか、接続待機タイムアウト属性が指定されていれば待機するかのいずれかです。
すべての使用可能な接続に対して繰り返して、接続の最低コストがInteger.MAX_VALUE
よりも低い場合、その接続に対してconfigureメソッドをコールし、その接続を戻します。複数の接続がInteger.MAX_VALUE
を下回る場合は、最低コストの接続を戻します。
追加のgetRequestedLabels()
メソッドを含む拡張コールバック・インタフェースoracle.ucp.jdbc.ConnectionLabelingCallback
もあります。リクエストしたラベルが提供されておらず、登録されているインスタンスがある場合、getConnection()
時にgetRequestedLabels
が呼び出されます。これは、標準のjava.sql.Datasource
getConnection()
メソッドが使用され、そのgetConnection()
コールでラベル情報が指定されていない場合に実行されます。
次のコード例では、cost
とconfigure
の両メソッドを実装する単純なラベリング・コールバックの実装を示します。このコールバックは、特定のトランザクション分離レベルで初期化されるラベル付けされた接続の検出に使用されます。
例6-1 ラベリング・コールバック
import oracle.ucp.jdbc.ConnectionLabelingCallback; import oracle.ucp.jdbc.LabelableConnection; import java.util.Properties; import java.util.Map; import java.util.Set; import weblogic.jdbc.extensions.WLDataSource; class MyConnectionLabelingCallback implements ConnectionLabelingCallback { public MyConnectionLabelingCallback() { } public int cost(Properties reqLabels, Properties currentLabels) { // Case 1: exact match if (reqLabels.equals(currentLabels)) { System.out.println("## Exact match found!! ##"); return 0; } // Case 2: some labels match with no unmatched labels String iso1 = (String) reqLabels.get("TRANSACTION_ISOLATION"); String iso2 = (String) currentLabels.get("TRANSACTION_ISOLATION"); boolean match = (iso1 != null && iso2 != null && iso1.equalsIgnoreCase(iso2)); Set rKeys = reqLabels.keySet(); Set cKeys = currentLabels.keySet(); if (match && rKeys.containsAll(cKeys)) { System.out.println("## Partial match found!! ##"); return 10; } // No label matches to application's preference. // Do not choose this connection. System.out.println("## No match found!! ##"); return Integer.MAX_VALUE; } public boolean configure(Properties reqLabels, Object conn) { try { String isoStr = (String) reqLabels.get("TRANSACTION_ISOLATION"); ((Connection)conn).setTransactionIsolation(Integer.valueOf(isoStr)); LabelableConnection lconn = (LabelableConnection) conn; // Find the unmatched labels on this connection Properties unmatchedLabels = lconn.getUnmatchedConnectionLabels(reqLabels); // Apply each label <key,value> in unmatchedLabels to conn for (Map.Entry<Object, Object> label : unmatchedLabels.entrySet()) { String key = (String) label.getKey(); String value = (String) label.getValue(); lconn.applyConnectionLabel(key, value); } } catch (Exception exc) { return false; } return true; } public java.util.Properties getRequestedLabels() { Properties props = new Properties(); // Set based on some application state that might be on a thread-local, http session info, etc. String value = ”value”; props.put("TRANSACTION_ISOLATION”, value); return props; } }
WLSデータ・ソースは、ラベリング・コールバックを登録するためのregisterConnectionLabelingCallback(ConnectionLabelingCallback callback)
メソッドを備えています。1つの接続プールに登録できるコールバックは1つのみです。次のコード例では、MyConnectionLabelingCallback
クラスに実装されているラベリング・コールバックの登録を示します。
. . . import weblogic.jdbc.extensions.WLDataSource; . . . MyConnectionLabelingCallback callback = new MyConnectionLabelingCallback(); ((WLDataSource)ds).registerConnectionLabelingCallback( callback ); . . .
管理コンソールを使用してコールバックを登録することもできます。Oracle WebLogic Server管理コンソール・ヘルプの「接続ラベリング・コールバック・クラスの構成」を参照してください。
次のいずれかの方法を使用して、ラベリング・コールバックを削除できます。
プログラムでコールバックを設定した場合、次の例に示されているようにremoveConnectionLabelingCallback()
メソッドを使用します。
. . . import weblogic.jdbc.extensions.WLDataSource; . . . ((WLDataSource)ds).removeConnectionLabelingCallback( callback ); . . .
管理者としてコールバックを設定した場合、データ・ソース構成からコールバックを削除します。Oracle WebLogic Server管理コンソール・ヘルプの「接続ラベリング・コールバック・クラスの構成」を参照してください。
注意: アプリケーションでは、コールバックを登録するメソッドとコールバックを削除するメソッドのうちの一方(両方ではない)を使用する必要があります。たとえば、 |
ラベルは、LabelableConnection
インタフェースのapplyConnectionLabel
メソッドを使用して、予約された接続に適用されます。任意の数の接続ラベルを予約された接続に累積的に適用できます。ラベルが接続に適用されるたびに、指定されたキー/値のペアが、ラベルの既存コレクションに追加されます。最後に適用された値のみがどのキーに対しても保持されます。
注意: 予約された接続にラベルを適用するには、ラベリング・コールバックを接続プールに登録する必要があります。登録しないと、ラベリングは無視されます。「ラベリング・コールバックの作成」を参照してください。 |
次の例では、トランザクション分離レベルで接続を初期化した後、ラベルを接続に適用しています。
. . . String pname = "property1"; String pvalue = "value"; Connection conn = ds.getConnection(); // initialize the connection as required. conn.setTransactionIsolation(Connection.TRANSACTION_SERIALIZABLE); ((LabelableConnection) conn).applyConnectionLabel(pname, pvalue); . . .
WLSデータ・ソースは、プールからラベル付けされた接続を予約するために使用する2つのgetConnection
メソッドを提供しています。これらのメソッドを次に示します。
public Connection getConnection(java.util.Properties labels) throws SQLException;
public Connection getConnection(String user, String password, java.util.Properties labels) throws SQLException;
これらのメソッドには、getConnection
メソッドにProperties
オブジェクトとして渡すラベルが必要です。次の例では、property1 valueというラベルが付いた接続の取得を示します。
. . . import weblogic.jdbc.extensions.WLDataSource; . . . String pname = "property1"; String pvalue = "value"; Properties label = new Properties(); label.setProperty(pname, pvalue); . . . Connection conn = ((WLDataSource)ds).getConnection(label); . . .
標準のjava.sql.Datasource getConnection()
メソッドを使用することもできます。この場合、getConnection()
コールでラベル情報は指定しません。oracle.ucp.jdbc.ConnectionLabelingCallback
インタフェースを使用します。
java.util.Properties getRequestedLabels();
リクエストしたラベルが提供されておらず、登録されているインスタンスがある場合、getConnection()
時にgetRequestedLabels
が呼び出されます。
1つの接続は複数のラベルを保有できます。各ラベルは目的とする条件に基づいて一意に接続を識別します。getUnmatchedConnectionLabels
メソッドは、リクエストされたラベルから、どの接続ラベルが一致してどの接続ラベルが一致しなかったかを検証するために使用されます。このメソッドは、複数のラベルを持つ接続が接続プールから予約された後に使用され、通常、ラベリング・コールバックで使用されます。次のコード例では、不一致ラベルのチェックを示します。
. . . String pname = "property1"; String pvalue = "value"; Properties label = new Properties(); label.setProperty(pname, pvalue); . . . Connecion conn = ((WLDataSource)ds).getConnection(label); Properties unmatched = ((LabelableConnection)connection).getUnmatchedConnectionLabels (label); . . .
removeConnectionLabel
メソッドは、接続からラベルを削除するために使用されます。このメソッドは、ラベル付けされた接続が接続プールから予約された後に使用されます。次のコード例では、接続ラベルの削除を示します。
. . . String pname = "property1"; String pvalue = "value"; Properties label = new Properties(); label.setProperty(pname, pvalue); Connection conn = ((WLDataSource)ds).getConnection(label); . . . ((LabelableConnection) conn).removeConnectionLabel(pname); . . .