この章の内容は次のとおりです。
この章では、プーリング動作を最適化するための接続プールのプロパティの設定方法について説明します。作成時に、UCP JDBC接続プールはデフォルト設定で事前構成されます。デフォルト設定により、一般的な汎用の接続プールとなります。しかし、アプリケーションにはそれぞれ異なるデータベース接続要件があり、接続プールのデフォルト動作の変更が必要な場合があります。プール・サイズや接続タイムアウトなどの動作を構成して、接続プール全体のパフォーマンスだけでなく接続の可用性も向上させることができます。多くの場合、特定のアプリケーションに合せて接続プールをチューニングする最善の方法は、最適なパフォーマンスおよびスループットを達成するまで、様々な値を使用して様々なプロパティの組合せを試すことです。
接続プールのプロパティの設定
接続プールのプロパティが設定されるのは、プール対応のデータソースを介して接続を取得するときか、接続プール・マネージャを使用して接続プールを作成するときです。
次の例では、プール対応のデータソースを介した接続プールのプロパティの設定を示します。
PoolDataSource pds = PoolDataSourceFactory.getPoolDataSource(); pds.setConnectionPoolName("JDBC_UCP"); pds.setMinPoolSize(4);pds.setMaxPoolSize(20); ...
次の例では、接続プール・マネージャを使用して接続プールを作成する場合の接続プールのプロパティの設定を示します。
UniversalConnectionPoolManager mgr = UniversalConnectionPoolManagerImpl. getUniversalConnectionPoolManager(); pds.setConnectionPoolName("JDBC_UCP"); pds.setMinPoolSize(4);pds.setMaxPoolSize(20); ... mgr.createConnectionPool(pds);
ヒント: UCP JDBC接続プールのプロパティは任意の順序で設定できます。また、実行時に動的に変更できます。たとえば、setMaxPoolSize はプールの作成後に変更できます。プールはその新しい値を認識し、その値に適応します。 |
UCP JDBC接続プールには、プール・サイズの制御に使用される一連のプロパティがあります。これらのプロパティを使用すると、要求の増減につれて、プール内の接続数を増減できるようになります。この動的な動作は、不要な接続の維持に浪費される場合のあるシステム・リソースの節約に役立ちます。
初期プール・サイズのプロパティは、接続プールの初回作成時または再初期化時に作成される使用可能な接続の数を指定します。通常、このプロパティは、プールを最適なサイズにすることで、発生する起動時間を削減するために使用されます。
値0
は、接続を事前作成しないことを示します。デフォルト値は0
です。次の例では、初期プール・サイズの構成を示します。
pds.setInitialPoolSize(5);
初期プール・サイズのプロパティが最大プール・サイズのプロパティより大きい場合は、最大数の接続のみが初期化されます。
初期プール・サイズのプロパティが最小プール・サイズのプロパティより小さい場合は、初期数の接続のみが初期化され、最小プール・サイズ値を満たす十分な接続が作成されるまで維持されます。
最小プール・サイズのプロパティは、プールが保持する使用可能な接続および流用された接続の最小数を指定します。接続プールがまだ最小サイズに達していない場合は、常に指定された最小プール・サイズに戻ろうとします。たとえば、最小限度が10
に設定されている場合、まだ2つの接続しか作成および流用されていないときは、プールで保持される接続数は2
のままです。
このプロパティを使用すると、要求が減少するにつれてプール内の接続数を減らすことができます。同時に、システム・リソースが不要な接続の維持のために浪費されないようにします。
デフォルト値は0
です。次の例では、最小プール・サイズの構成を示します。
pds.setMinPoolSize(2);
最大プール・サイズのプロパティは、プールが保持する使用可能な接続および流用された(使用中の)接続の最大数を指定します。最大数の接続が流用された場合、プールに返されるまで接続は利用できません。
このプロパティを使用すると、要求が増加するにつれてプール内の接続数を増やすことができます。同時に、プールがシステムのリソースを使い果し、最終的にアプリケーションのパフォーマンスや可用性に影響を及ぼすほど大きくならないようにします。
値0
は、プールで保持される接続がないことを示します。接続を取得しようとすると例外が発生します。デフォルト値では、最大でInteger.MAX_VALUE
(デフォルトでは2147483647)まで接続を作成し続けることができます。次の例では、最大プール・サイズの構成を示します。
pds.setMaxPoolSize(100);
失効した接続とは、使用可能であるか流用中であるにもかかわらず、使用されなくなった接続です。流用されたままの失効した接続は、接続の可用性に影響を及ぼすことがあります。また、失効した接続があると、使用されていない接続を長期間維持するためにリソースが浪費されることから、システム・リソースに影響を及ぼすことがあります。この項で説明するプール・プロパティを使用して、失効した接続を制御します。
注意: アプリケーションで不要になった接続はすべてクローズすることをお薦めします。接続をクローズすると、流用されたままの失効した接続の数を少なくすることができます。 |
接続再利用機能を使用すると、一定の時間が経過した後または接続が一定の回数使用された後に、接続を適切にクローズして接続プールから削除できます。また、使用できない接続の維持に浪費されることになるシステム・リソースを節約します。
最大接続再使用時間を使用すると、一定の時間使用された後に、接続を適切にクローズしてプールから削除できます。このプロパティのタイマーは、接続が物理的に作成されると開始します。流用された接続はプールに返された後にしかクローズされないため、再使用時間を超過します。
通常、この機能は、ファイアウォールがプール層とデータベース層の間に存在し、時間制限に基づいて接続をブロックするように設定されている場合に使用されます。ブロックされた接続は、使用できないにもかかわらずプールに残存します。このような場合、接続再使用時間をファイアウォールのタイムアウト・ポリシーより小さい値に設定します。
注意: 最大接続再使用時間は、TTL接続タイムアウトとは異なります。TTL接続タイムアウトは、接続がプールから流用されると開始します。一方、最大接続再使用時間は、接続が物理的に作成されると開始します。また、TTLタイムアウトでは、流用期間中にタイムアウトの期限が切れると、接続をクローズして再利用のためにプールに返します。最大接続再使用時間では、タイムアウトの期限が切れると、接続をクローズしてプールから破棄します。「TTL接続タイムアウトの設定」を参照してください。 |
最大接続再使用時間の値は秒単位です。値0
は、この機能が無効であることを示します。デフォルト値は0
です。次の例では、最大接続再使用時間の構成を示します。
pds.setMaxConnectionReuseTime(300);
中止接続タイムアウトを使用すると、流用された接続が一定時間使用されなかった場合に、接続プールに戻すことができます。中止の決定は、データベースへのコールを監視することで行われます。このタイムアウト機能は、接続再利用が最大限になるようにし、使用されていない流用された接続の維持に浪費されることになるシステム・リソースを節約します。
注意: UCP for JDBCでは、再利用のために接続を回収する前に、ローカル・トランザクションが保留中である接続を取り消すかロールバックします。 |
中止接続タイムアウトの値は秒単位です。値0
は、この機能が無効であることを示します。デフォルト値は0
に設定されます。次の例では、中止接続タイムアウトの構成を示します。
pds.setAbandonConnectionTimeout(10);
TTL接続タイムアウトを使用すると、流用された接続を一定時間流用されたままにした後で、接続をプールに回収できます。このタイムアウト機能は、接続が最大限に再利用されるようにし、想定される使用時間よりも長く接続を維持するために浪費されることになるシステム・リソースの節約に役立ちます。
注意: UCP for JDBCでは、再利用のために接続を回収する前に、ローカル・トランザクションが保留中である接続を取り消すかロールバックします。 |
TTL接続タイムアウトの値は秒単位です。値0
は、この機能が無効であることを示します。デフォルト値は0
に設定されます。次の例では、TTL接続タイムアウトの構成を示します。
pds.setTimeToLiveConnectionTimeout(18000)
接続待機タイムアウトは、プールに接続がなくなった場合にアプリケーション・リクエストが接続を取得するために待機する時間を指定します。プール内の接続がすべて使用されている(流用されている)場合、およびプール・サイズが最大プール・サイズのプロパティで指定されている最大接続許容数に達している場合、接続プールには接続がなくなります。タイムアウト値に達すると、リクエストはSQL例外を受け取ります。その場合、アプリケーションは接続の取得を再試行できます。このタイムアウト機能により、アプリケーションがブロックされる時間を最小限にすることでアプリケーション全体の有用性が向上し、適切なリカバリを実行できます。
接続待機タイムアウトの値は秒単位です。値0
は、この機能が無効であることを示します。デフォルト値は3
秒に設定されます。次の例では、接続待機タイムアウトの構成を示します。
pds.setConnectionWaitTimeout(10);
非アクティブ接続タイムアウトは、クローズしてプールから削除されるまでの、使用可能な接続がアイドル状態でいられる時間を指定します。このタイムアウト・プロパティは、使用可能な接続にのみ適用でき、流用された接続には作用しません。このプロパティは、使用されなくなった接続の維持に浪費されることになるリソースの節約に役立ちます。非アクティブ接続タイムアウトを(最大プール・サイズとともに)使用すると、アプリケーション・ロードが変化するにつれて接続プールを拡大または縮小できます。
非アクティブ接続タイムアウトの値は秒単位です。値0
は、この機能が無効であることを示します。デフォルト値は0
に設定されます。次の例では、非アクティブ接続タイムアウトの構成を示します。
pds.setInactiveConnectionTimeout(60);
タイムアウト・チェック間隔プロパティは、タイムアウト・プロパティ(中止接続タイムアウト、TTL接続タイムアウトおよび非アクティブ接続タイムアウト)が適用される頻度を制御します。タイムアウトした接続は、タイムアウト・チェック・サイクルの実行時に回収されます。つまり、接続のタイムアウト時に、実際には接続がプールに回収されないことがあります。接続のタイムアウトと実際の接続の回収の間のラグ・タイムは、タイムアウト・チェック間隔の長さによっては非常に大きい場合があります。
タイムアウト・チェック間隔プロパティは秒単位です。デフォルト値は30
に設定されます。次の例では、タイムアウト・チェック間隔プロパティの構成を示します。
pds.setTimoutCheckInterval(60);
接続獲得機能を使用すると、接続プールが指定された使用可能な接続数に達したときに、指定された数の流用された接続を回収できます。この機能は、プール内で一定数の接続を常に使用可能な状態にし、パフォーマンスの最大化に役立ちます。特に、アプリケーションで接続ハンドルをキャッシュする場合に便利です。通常、キャッシングはパフォーマンス上の理由から実行されます。これは、キャッシングにより、接続がトランザクションに参加するために必要となる状態の再初期化が最小限になるためです。
たとえば、接続はプールから流用され、必要なセッション状態で初期化された後、コンテキスト・オブジェクト内に保持されます。この方法で接続を保持することが、接続プールに使用可能な接続がなくなる原因になる可能性があります。接続獲得機能では、該当する場合に、流用された接続を回収して再利用できるようにします。
接続獲得は、HarvestableConnection
インタフェースを使用して制御し、接続獲得トリガー数と接続獲得最大数の2つのプール・プロパティを使用して構成または有効にします。接続獲得機能を実装するときは、これらのインタフェースおよびプロパティを併用します。
oracle.ucp.jdbc.HarvestableConnection
インタフェースのsetConnectionHarvestable(boolean)
メソッドは、接続を獲得するかどうかを制御します。このメソッドは、接続獲得が有効である場合にロック・メカニズムとして使用されます。たとえば、トランザクション内で接続が使用されていて接続の獲得を禁止する場合、このメソッドを接続に対してfalse
に設定します。トランザクションの完了後、このメソッドを接続に対してtrue
に設定すると、必要に応じて接続を獲得できます。
注意: 接続獲得機能が有効である場合、デフォルトではすべての接続が獲得可能です。この機能が有効である場合、接続が獲得可能かどうかを明示的に制御するため、setConnectionHarvestable メソッドを常に使用する必要があります。 |
次の例では、接続獲得機能で接続を獲得しようとしても接続が獲得不可であることを示す、setConnectionHarvestable
メソッドの使用例を示しています。
Connection conn = pds.getConnection(); ((HarvestableConnection) conn).setConnectionHarvestable(false);
接続獲得トリガー数は、接続獲得をトリガーする使用可能な接続のしきい値を指定します。たとえば、接続獲得トリガー数を10に設定した場合、プール内の使用可能な接続数が10まで減少すると、接続獲得がトリガーされます。
値Integer.MAX_VALUE
(デフォルトでは2147483647)は、接続獲得が無効であることを示します。デフォルト値はInteger.MAX_VALUE
です。
次の例では、接続獲得トリガー数を構成して接続獲得を有効にしています。
pds.setConnectionHarvestTriggerCount(2);
接続獲得最大数プロパティは、獲得トリガー数に達した場合に、プールに返す必要がある流用された接続の数を指定します。実際に獲得される接続数は、0から接続獲得最大数の値までのいずれかです。最も長い間使用されていない接続から先に獲得されるため、非常にアクティブなユーザー・セッションが最大限に接続を保つことができます。
獲得最大数の値の範囲は、0
から最大接続数プロパティの値までです。デフォルト値は1
です。範囲外の値を指定すると、SQL例外がスローされます。
次の例では、接続獲得最大数の構成を示します。
pds.setConnectionHarvestMaxCount(5);
注意:
中止接続タイムアウト機能およびTTL接続タイムアウト機能の詳細は、第6章を参照してください。 |
文キャッシングにより、文の処理はより効率的になります。文キャッシングでは、繰り返し使用される実行可能な文をキャッシングすることでパフォーマンスが向上し、プログラマがコンパイル済の文を明示的に再利用する必要がなくなります。また、繰り返されるカーソルの作成、繰り返される文の分析および作成によるオーバーヘッドを解消し、アプリケーションとデータベース間の通信のオーバーヘッドを削減します。文キャッシングと再利用は、アプリケーションに対して透過的です。各文キャッシュは、物理的な接続に関連付けられます。つまり、物理的な接続はそれぞれ独自の文キャッシュを保有します。
キャッシュされた文の一致条件は次のとおりです。
文のSQL文字列は、キャッシュ内のものと同一(大/小文字を区別)である必要があります。
文の種類は、キャッシュ内のものと同一(prepared
またはcallable
)である必要があります。
文によって生成される結果セットのスクロール可能タイプは、キャッシュ内のものと同一(forward-only
またはscrollable
)である必要があります。
文キャッシングは、JDBCドライバのベンダーによって異なる方法で実装および有効化されます。この項の説明は、OracleのJDBCドライバ固有のものです。他のベンダーのドライバでの文キャッシングは、コネクション・ファクトリで接続プロパティを設定することで構成できます。接続プロパティの設定の詳細は、「接続プロパティの設定」を参照してください。また、JDBCベンダーのドキュメントを参照して、文キャッシングがサポートされているかどうか、接続プロパティとして設定できるかどうかを確認してください。UCP for JDBCでは、JDBCベンダーが文プーリングをサポートする場合は、文プーリングを有効にするためのJDBC 4.0(JDK16)APIがサポートされません。
最大文数プロパティは、接続ごとにキャッシュする文の数を指定します。このプロパティは、Oracle JDBCドライバにのみ適用できます。このプロパティを設定しない場合、または0
に設定する場合、文キャッシングは無効になります。デフォルトでは、文キャッシングは無効です。文キャッシングを有効にすると、文キャッシュは、接続プールで保持される物理的な接続のそれぞれに関連付けられます。1つの文キャッシュは、すべての物理的な接続で共有されません。
次の例では、文キャッシングの有効化を示します。
pds.setMaxStatements(10);
文キャッシュ・サイズの決定
キャッシュ・サイズは、アプリケーションがデータベースに対して発行する個々の文の数に設定する必要があります。アプリケーションがデータベースに対して発行する文の数が不明な場合、JDBCパフォーマンス・メトリックを使用して文キャッシュ・サイズの決定に役立てます。
文キャッシュ・サイズのリソース問題
接続はそれぞれ独自の文キャッシュに関連付けられます。接続の文キャッシュ内に保持される文が、データベース・リソースを保持し続ける場合があります。オープンされた接続の数と各接続のキャッシュされた文の数の合計が、データベースで許容されるオープン・カーソルの限度を超える可能性があります。この問題は、キャッシュ内で許容される文の数を減らすか、データベースで許容されるオープン・カーソルの限度を増やすかすることで、回避できます。