Oracle Fusion Middleware Oracle WebLogic Server JDBCデータ・ソースの構成と管理 11g リリース1 (10.3.6) B60997-05 |
|
前 |
次 |
この章では、Oracleのドライバおよびデータベースの使用時にデータ・ソースおよびドライバのパフォーマンスを向上させる詳細構成オプションについて説明します。オプションには、プロキシ認証、接続の資格証明の設定、接続収集、および接続のラベリングがあります。
WebLogic Serverは、Oracleドライバ使用時にデータ・ソース・パフォーマンスを向上させるいくつかの属性を提供します。これには次が含まれます。
Oracle Enable JavaNet Fastpath: Oracle JDBC JavaNet Fastpathを有効化して、データ・コピーおよびフラグメンテーションを低減させます。
Oracle Optimize UTF8 Conversion: 「Oracle JDBC Optimize UTF8 Conversion」オプションを有効化します。
ご使用の環境でこれらの属性がサポートされている場合、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パラメータの構成に関する項を参照してください。
プールで接続がリクエストされるたびに、アプリケーション認証されるユーザーに対する接続でプロキシ・セッションが開かれます。接続がプールに戻されると、プロキシ・セッションが閉じられます。
注意: プロキシ・セッションを開くか閉じる場合:
これらの動作は、インスタンス間で接続を共有し、ある状態が接続に関連付けられていると想定するアプリケーションに影響を及ぼす可能性があります。 |
Oracleデータベースへの接続時に接続によってデータベース資格証明が設定されるように、WebLogicデータ・ソースを構成できます。構成した場合、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()
リクエストのプロキシ・ユーザーとの接続を戻すことがあります。この機能をグローバル・トランザクションで使用する際は、単一データベース・ユーザー名
を指定することをお薦めします。
データ・ソースで使用可能な接続が、指定された数に達した場合に解放される予約済接続の数を指定できます。収集は、指定された数の接続が常に使用可能であるようにすることに役立ち、接続の初期化を最小限にすることでパフォーマンスを向上させます。
接続収集は、アプリケーションで接続ハンドルがキャッシュされる場合に特に有用です。キャッシングは一般に、パフォーマンス上の理由で行われます。接続がトランザクションに参加するために必要な状態の初期化を最小限に抑えることができるためです。たとえば、接続はデータ・ソースから予約され、必要なセッション状態に初期化されてから、コンテキスト・オブジェクトに格納されます。この方法で接続を保留すると、接続プール内の使用可能な接続が不足することがあります。接続収集により、予約済の接続が適宜再要求され、接続の再利用が可能になります。
アプリケーションで接続収集を使用するには、次の手順を使用します:
データ・ソース構成の「接続収集トリガー数」
属性は、接続収集をトリガーするしきい値を有効にし、指定するために使用されます。たとえば、「接続収集トリガー数」
が10に設定されている場合、接続収集は有効で、使用可能な接続の数が減って10になると、データ・ソースが予約済接続の収集を開始します。値-1は、接続収集が無効なことを表します。
接続収集がトリガーされる場合、「接続収集最大数」
によって、プールに戻すことのできる予約済接続の数が指定されます。実際に収集される接続の数は、1から接続収集最大数
の値までです。
Oracle WebLogic Server管理コンソール・ヘルプの接続プールに対する接続収集の構成に関する項を参照してください。
接続収集が有効になると、すべての接続が収集可能になります。接続を収集可能にしない場合は、oracle.ucp.jdbc.HarvestableConnection
インタフェース内のsetConnectionHarvestable(
boolean
)
メソッドを引数値false
で呼び出し、その接続を収集不可として明示的にマークする必要があります。
たとえば、トランザクションがトランザクション内部で使用されている場合に収集を行わないようにする場合は、次の文を使用します。
. . . 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
メソッドの結果は、接続を必要な状態に再構成するために必要な見積りコストを表す整数です。値が大きいほど、接続の再構成にかかるコストは高くなります。接続プールは常に、コスト値が最も低い接続を戻します。アルゴリズムは次のとおりです。
コスト・メソッドが接続に対して0を戻す場合、接続は一致しています(requestedLabels
とcurrentLabels
が一致しているとは限りませんので注意してください)。接続プールは見つかった接続に対してconfigureを呼び出さず、単にその接続を戻します。
コスト・メソッドが0以外(負または正の整数)を戻す場合、接続プールは、コスト値が0の接続が見つかるか、使用可能な接続が足りなくなるまで繰り返します。
プールがすべての使用可能な接続に対して繰り返しても、接続の最小コストがInteger.MAX_VALUE
(デフォルトは2147483647)である場合、接続リクエストに適合する接続はプール内に存在しないということです。プールは新しい接続を作成し、その接続でconfigure
メソッドを呼び出して、この新しい接続を戻します。プールが最大プール・サイズに達した場合(新しい接続を作成できない場合)、プールはSQL例外をスローするか、接続待機タイムアウト属性が指定されていれば待機します。
プールがすべての使用可能な接続に対して繰り返しても、接続の最小コストがInteger.MAX_VALUE
である場合、その接続でconfigureメソッドが呼び出されてから、接続が戻されます。接続数がInteger.MAX_VALUE
より少ない場合、最もコストの低い接続が戻されます。
また、さらにgetRequestLabels()
メソッドも含まれる拡張コールバック・インタフェース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
メソッドを使用して予約済接続に適用されます。接続ラベルは、累積的に予約済接続に適用されます。ラベルが接続に適用されるたびに、指定されたキーと値のペアが既存のラベルの集まりに追加されます。最後に適用された値のみが、特定のキーに対して保持されます。
注意: 予約済の接続にラベルを適用する前に、ラベリング・コールバックを接続プールに登録しておく必要があります。そうしない場合、ラベリングは無視されます。第6章「ラベリング・コールバックの作成」を参照してください。 |
次の例は、トランザクション分離レベルで接続を初期化して、その接続にラベルを適用する方法を示しています。
. . . 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;
これらのメソッドでは、ラベルがProperties
オブジェクトとしてgetConnection
メソッドに渡される必要があります。次の例は、property1値のラベルが付いた接続を取得する方法を示しています。
. . . 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
が呼び出されます。
接続には複数のラベルを持つものがあり、各ラベルは特定の基準に基づいて一意に接続を識別します。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); . . .