28 データベース常駐接続プーリング
データベース常駐接続プール(DRCP)は、多くのクライアントが共有できるサーバーの接続プールです。DRCPは、特定の時点でアクティブな接続の数が、オープンしている接続の数よりも適度に少ない場合に使用します。DRCPは、多数の中間層サーバーを使用するアプリケーションで特に役立ちます。データベース常駐接続プーリング機能を使用すると、データベース・サーバーのスケーラビリティが向上し、中間層接続プーリングのリソース浪費の問題が解決されます。
この章の構成は、次のとおりです。
28.1 データベース常駐接続プーリングの概要
中間層の接続プールでは、すべての接続プールが、サーバーに対して最低限の数の接続をオープンしています。オープンしている各接続が、サーバーで使用されているリソースを表します。ただし、アプリケーションが特定の時点でオープンしているすべての接続を使用するわけではありません。つまり、サーバー・リソースを不必要に消費する未使用のリソースがあることを意味します。複数の中間層のシナリオでは、各中間層が他の中間層接続プールと接続を共有せずに個々の接続プールを維持し、それらのいくつかが非アクティブであっても、オープンしている接続を長期間保持します。多数の中間層接続プールを持つアプリケーションの場合、データベース・サーバーへの非アクティブ接続の数が非常に多くなり、大量のデータベース・リソースを浪費します。
たとえば、アプリケーション内で、すべての中間層の接続プールの最小プール・サイズが200の場合、接続プールにはサーバーに対してオープンしている200の接続があり、データベース・サーバーにはこれらの接続に関連付けられた200のサーバー・プロセスがあります。アプリケーションに同様の中間層接続プールが30個ある場合、サーバーには任意の時点で6000 (200 * 30)個の対応するサーバー・プロセスが実行していることになります。通常、平均で接続の5%のみ、そしてサーバー・プロセスが同時に使用されています。したがって、常に、6,000個のサーバー・プロセスのうちアクティブな接続は300個のみです。これにより、サーバー上で5,700個の未使用プロセスが発生し、結果としてサーバー上のリソースが無駄になります。
データベース常駐接続プールを実装すると、Databaseサーバー側でプールが作成され、複数のクライアント・プール間でこれが共有されます。これによって、同時に実行されるサーバー・プロセス数が減少するため、データベース・サーバーでのメモリー消費量が著しく減少し、そのスケーラビリティが向上します。
28.2 データベース常駐接続プーリングを使用可能にする方法
この項では、サーバー側とクライアント側でデータベース常駐接続プーリング(DRCP)を有効にする方法について説明します。
28.2.1 サーバー側でDRCPを使用可能にする方法
データベース常駐接続プール(DRCP)を起動して終了するには、データベース管理者(DBA)であり、SYSDBA
としてログインする必要があります。この項では、次の関連概念について説明します。
ノート:
JDBCにはデフォルトのプールがないため、DRCP機能はクライアントの接続プールでしか利用できません。データベース常駐接続プールの開始
DBMS_CONNECTION_POOL
パッケージ内のstart_pool
メソッドをデフォルト設定で実行して、デフォルトのOracle Database常駐接続プール(つまり、SYS_DEFAULT_CONNECTION_POOL
)を起動します。たとえば:
sqlplus /nolog connect / as sysdba execute dbms_connection_pool.start_pool();
データベース常駐接続プールの構成
DBMS_CONNECTION_POOL
パッケージ内のプロシージャを使用して、デフォルトのOracle Database常駐接続プールを構成します。デフォルトでは、この接続プールはデフォルトのパラメータ値を使用します。
データベース常駐接続プールの終了
DBMS_CONNECTION_POOL
パッケージ内のstop_pool
メソッドを実行して、プールを終了します。たとえば:
sqlplus /nolog connect / as sysdba execute dbms_connection_pool.stop_pool();
文のキャッシュ・サイズの設定
DRCPを使用する場合、サーバーはサーバー側で文情報をキャッシュします。したがって、次のように、サーバー側で文のキャッシュ・サイズを指定する必要があります。50が最適サイズです。
execute DBMS_CONNECTION_POOL.CONFIGURE_POOL (session_cached_cursors=>50);
関連トピック
28.2.2 クライアント側でDRCPを使用可能にする方法
クライアント側でDRCPを使用可能にするには、次のステップを実行します。
ノート:
この項の例は、クライアント側の接続プールとしてユニバーサル接続プール(UCP)を使用します。他の接続プールの場合は、oracle.jdbc.pool.OracleConnectionPoolDataSource
を接続ファクトリとして使用する必要があります。
-
null以外で空でない
String
値をoracle.jdbc.DRCPConnectionClass
接続プロパティに渡します -
(
SERVER=POOLED
)をCONNECT_DATA
構成パラメータに長い接続文字列で追加します
(<service_name>=POOLED)
を、次のように短い接続文字列で指定することもできます。
jdbc:oracle:thin:@<host>:<port>/<service_name>[:POOLED]
たとえば:
jdbc:oracle:thin:@localhost:5221/orcl:POOLED
次のコード・スニペットは、クライアント側でDRCPを有効にする方法を示しています。
ノート:
UCPでは、接続クラスを指定しない場合、接続プール名がデフォルトで接続クラス名として使用されます。
例28-1 ユニバーサル接続プールを使用してクライアント側でDRCPを使用可能にする方法
String url = "jdbc:oracle:thin:@localhost:5521/orcl:POOLED"; PoolDataSource pds = PoolDataSourceFactory.getPoolDataSource(); pds.setConnectionFactoryClassName("oracle.jdbc.pool.OracleDataSource"); // Set DataSource Property pds.setUser("HR"); pds.setPassword("hr"); System.out.println ("Connecting to " + url); pds.setURL(url); pds.setConnectionPoolName("HR-Pool1"); pds.setMinPoolSize(2); pds.setMaxPoolSize(3); pds.setInitialPoolSize(2); Properties prop = new Properties(); prop.put("oracle.jdbc.DRCPConnectionClass", "HR-Pool1"); pds.setConnectionProperties(prop);
28.3 複数の接続プール間でプールされたサーバー・プロセス
サーバー上でプールされたすべてのサーバー・プロセスに同じデータベース常駐接続プール(DRCP)接続クラス名を設定し、サーバー上の複数の接続プール間でそれらを共有できます。DRCP接続クラス名を設定するには、oracle.jdbc.DRCPConnectionClass
接続プロパティを使用します。
28.4 DRCPでのマルチプールのサポート
複数の名前付きDRCPプールを使用するアプリケーションを開発できるようになりました。これは、少数のサービスからの接続でDRCPのプールされたサーバーがすべて占有され、他のサービスからの接続はプールされたサーバーが使用可能になるまで待つ必要があるという状況を避けるために役立ちます。
DRCPで適切なプールを接続に示すには、次の例のように、接続文字列で(POOL_NAME=<pool_name>)
を(SERVER=POOLED)
とともに指定します。
(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)(HOST=<host>)(PORT=<port>))
(CONNECT_DATA=(SERVER=POOLED)(POOL_NAME=<pool_name>)))
DRCPプールの作成はすべてのサービスに対して必須なわけではなく、一部のサービスでマルチプールDRCPを使用することや、残りのサービスでPDB単位またはCDB全体のDRCPを共有することができます。PDB管理者である場合は、PDBに接続することで、DRCPの作成や破棄などの管理操作の実行もできます。
プールされたサーバーをマルチプールDRCPに対して追加および削除する、次のプロシージャがDBMS_CONNECTION_POOL
パッケージに追加されました。
ADD_POOLプロシージャ
このプロシージャにより、新しいプールをマルチプールDRCPに追加します。たとえば:
exec dbms_connection_pool.add_pool('mypool')
REMOVE_POOLプロシージャ
このプロシージャにより、新しいプールをマルチプールDRCPから削除します。たとえば:
exec dbms_connection_pool.remove_pool('mypool')
28.5 データベース常駐接続プーリングでのタグ付けサポート
データベース常駐接続プーリング(DRCP)には、サーバー・プロセスを特定のタグ名に関連付けるオプションが用意されています。特定の接続にタグを適用し、後でそのタグ付けされた接続を取得できます。接続にタグを付けると、特定のセッションを簡単に取り出せるようになり、セッション・プーリングが強化されます。
DRCPでは、複数のタグ付けもサポートされており、デフォルトでは無効になっています。この機能をDRCPアプリケーションで有効にするには、oracle.jdbc.UseDRCPMultipletag
接続プロパティをTRUE
に設定します。
複数のタグ付け機能を有効にすると、1つ以上のDRCPタグに同じAPIを使用できます。違いはセパレータのみです。DRCPタグのキーと値は等号(=
)文字で区切る必要がありますが、複数のタグはセミコロン(;
)文字で区切る必要があります。
DRCPタグの使用時には次の点に注意してください。
-
タグのキーまたは値をnullまたは空として指定することはできません。
-
複数のタグを指定する場合、左端のタグの優先度が最も高く、右端のタグの優先度が最も低くなります。
-
タグ付けされた接続を取得する際に、完全一致が見つからない(すべてのタグが一致しない)場合、部分一致を検索します。
RESET_STATE
サービス属性をLEVEL1
またはLEVEL2
に設定することはできません。
関連項目:
セッション・プーリングと接続のタグ付けの詳細は、『Oracle Call Interfaceプログラマーズ・ガイド』を参照してください。28.6 セッション状態の修正のためのPL/SQLコールバック
Oracle Database 12cリリース2 (12.2.0.1)以降、セッション状態のPL/SQLベースの修正コールバックをサーバーで提供できるようになりました。このアプリケーションで提供されたコールバックは、プールからチェックアウトされたセッションをアプリケーションで要求された必要な状態に変換します。このコールバックは、データベース常駐接続プーリング(DRCP)があってもなくても動作します。
ノート:
PL/SQLベースの修正コールバックは、複数のタグ付けの場合にのみ適用できます。
このコールバックを使用すると、修正ロジックがサーバー上のセッション状態に対して実行されるため、アプリケーションのパフォーマンスを改善できます。したがって、修正ロジックのために、この機能によりデータベースへのアプリケーションのラウンドトリップがなくなります。関連するパッケージで実行権限を付与されている適切なインストール・ユーザーは、アプリケーションのインストール時に修正コールバックを登録する必要があります。
例28-2 PL/SQLの修正コールバックの例
次に、セッション・プロパティSCHEMA
およびCURRENCY
を修正するためのPL/SQL修正コールバックの実装例を示します。
CREATE OR REPLACE PACKAGE mycb_pack AS
PROCEDURE mycallback (
desired_props IN VARCHAR2,
actual_props IN VARCHAR2
);
END;
/
CREATE OR REPLACE PACKAGE BODY mycb_pack AS
PROCEDURE mycallback (
desired_props IN VARCHAR2,
actual_props IN VARCHAR2
) IS
property VARCHAR2(64);
key VARCHAR2(64);
value VARCHAR2(64);
pos number;
pos2 number;
pos3 number;
idx1 number;
BEGIN
idx1:=1;
pos:=1;
pos2:=1;
pos3:=1;
property := 'tmp';
-- To check if desired properties are part of actual properties
while (pos > 0 and length(desired_props)>pos)
loop
pos := instr (desired_props, ';', 1, idx1);
if (pos=0)
then
property := substr (desired_props, pos2);
else
property := substr (desired_props, pos2, pos-pos2);
end if ;
pos2 := pos+1;
pos3 := instr (property, '=', 1, 1);
key := substr (property, 1, pos3-1);
value := substr (property, pos3+1);
if (key = 'CURRENCY') then
EXECUTE IMMEDIATE 'ALTER SESSION SET NLS_CURRENCY=''' || value || '''';
elsif (key = 'SCHEMA') then
EXECUTE IMMEDIATE 'ALTER SESSION SET CURRENT_SCHEMA=' || value;
end if;
idx1 := idx1+1;
end loop;
END; -- mycallback
END mycb_pack;
/