3.1 UCPからの接続の流用について
アプリケーションは、プール対応のデータソースを使用して接続を流用します。この項では、接続の流用に関する次の概念について説明します。
ノート:
この項の説明では、プール対応のデータソースを使用して接続プールを暗黙的に作成および起動します。
3.1.1 UCPからの接続の流用の概要
UCP APIは、2つのプール対応のデータソースを備えています。1つは標準接続を流用するためのものであり、もう1つはXA接続を流用するためのものです。これらのデータソースは、UCP JDBC接続プール機能にアクセスでき、接続の流用に使用される一連のgetConnection
メソッドを備えています。XAと非XAのどちらのUCP JDBC接続プールにも同じプール機能があります。
UCP JDBC接続プールは、使用可能な接続と流用された接続の両方を保持します。アプリケーションが使用可能な接続と一致する接続の流用をリクエストすると、プールの接続が再利用されます。プール内の使用可能な接続がリクエストされた接続と一致しない場合は、新しい接続が作成されます。使用可能な接続と流用された接続の数は、プール・サイズ、タイムアウト間隔および検証ルールなどのプールのプロパティによって異なります。
3.1.1.1 バックグラウンド・スレッドを使用した接続作成
Oracle Databaseリリース23ai以降、新しい接続はユーザー・スレッドではなくバックグラウンド・スレッドを使用して作成されます。
次の両方の条件が満たされると、流用リクエストによって新しい接続作成がトリガーされる場合があります:
- リクエスト時にプールで使用可能な接続がない場合
- プールを拡大するのに十分な領域がある場合
流用リクエストは、次のうち最初に発生するイベントで満たされる場合があります:
- バックグラウンド・スレッドによって作成された新しい接続
- プールに返されたばかりの接続
接続の流用リクエストがConnectionWaitTimeout
(CWT)期間内に満たされない場合、UCP-29エラー・コードでUniveralConnectionPoolException
がスローされます。
この動作は、次の点でOracle Databaseリリース19cまたは21cとは異なります:
- CWTがゼロまたは非常に小さい値の場合、新しいJDBC接続の作成に十分な時間がないため、流用リクエストで例外をスローする可能性が高くなります。CWT期間がゼロの流用リクエストは、プールにすぐに使用可能なものがある場合にのみ接続を返すことができます。
- 接続リクエストによってスローされるUCP例外には、常に原因としてJDBC例外が含まれるとはかぎりません。ドライバがデータベースに接続できないような状況をトラブルシューティングするために、
ConnectionCreationInformation
コールバックを実装できます。 - 以前のリリースとは異なり、CWTは
CONNECT_TIMEOUT
パラメータの値で調整されません。
現在のデフォルトの動作では、ユーザー・スレッドではなくバックグラウンド・スレッドを使用して接続を作成するため、効率が向上します。必要に応じて、次の方法で古い動作に戻すことができます:
- 新しいシステム・プロパティ
oracle.ucp.createConnectionInBorrowThread
をtrue
に設定 setCreateConnectionInBorrowThread(boolean)
メソッドを使用してcreateConnectionInBorrowThread
フラグをtrue
に設定
3.1.2 プール対応のデータソースの使用方法
UCPは、データベースに接続するために使用されるプール対応のデータソース(oracle.ucp.jdbc.PoolDataSource
)を提供します。oracle.ucp.jdbc.PoolDataSourceFactory
ファクトリ・クラスは、プール対応のデータソース・インスタンスを作成するgetPoolDataSource()
メソッドを備えています。たとえば:
PoolDataSource pds = PoolDataSourceFactory.getPoolDataSource();
プール対応のデータソースには、実際の物理的な接続を取得するためにコネクション・ファクトリ・クラスが必要です。コネクション・ファクトリは通常、JDBCドライバの一部として提供され、データソースそのものにすることもできます。UCP JDBC接続プールでは任意のJDBCドライバを使用して物理接続を作成することができ、作成した接続はプールで管理されます。setConnectionFactoryClassName(String)
メソッドは、プール対応のデータソース・インスタンスにコネクション・ファクトリを定義するために使用されます。次の例では、Oracle JDBCドライバに付属するoracle.jdbc.pool.OracleDataSource
コネクション・ファクトリ・クラスを使用しています。別のベンダーが提供するJDBCドライバを使用する場合は、対応するベンダーのドキュメントで適切なコネクション・ファクトリ・クラスを参照してください。
pds.setConnectionFactoryClassName("oracle.jdbc.pool.OracleDataSource");
コネクション・ファクトリ・クラスに加えて、プール対応のデータソースには、データベースへの接続に使用されるURL、ユーザー名およびパスワードが必要です。プール対応のデータソース・インスタンスは、これらの各プロパティを設定するメソッドを備えています。次の例では、Oracle JDBC ThinドライバのURL構文を使用しています。別のベンダーが提供するJDBCドライバを使用する場合は、対応するベンダーのドキュメントで適切なURL構文を参照してください。
pds.setURL("jdbc:oracle:thin:@//localhost:1521/orcl"); pds.setUser("user"); pds.setPassword("password");
関連項目:
Oracle URL構文の使用方法は、『Oracle Database JDBC開発者ガイド』を参照してください。-
getConnection()
: データベースへの接続に使用されたユーザー名およびパスワードと関連付けられている接続を返します。 -
getConnection(String username, String password)
: 指定されたユーザー名およびパスワードと関連付けられている接続を返します。 -
getConnection(java.util.Properties labels)
: 指定されたラベルと一致する接続を返します。 -
getConnection(String username, String password, java.util.Properties labels)
: 指定されたユーザー名およびパスワードと関連付けられ、指定されたラベルと一致する接続を返します。
アプリケーションは、getConnection
メソッドを使用して、java.sql.Connection
タイプの接続ハンドルをプールから流用します。接続ハンドルが、リクエストされた接続(同じURL、ユーザー名およびパスワード)と一致するプールにすでに存在する場合は、それがアプリケーションに返されます。それ以外の場合は、新しい接続が作成され、新しい接続ハンドルがアプリケーションに返されます。次の例は、Oracle DatabaseとMySQL Databaseの接続をそれぞれ流用する方法を示しています。
Oracleのサンプル
次の例は、JDBC Thinドライバを使用した接続の流用を示しています。
PoolDataSource pds = PoolDataSourceFactory.getPoolDataSource(); pds.setConnectionFactoryClassName("oracle.jdbc.pool.OracleDataSource"); pds.setURL("jdbc:oracle:thin:@//localhost:1521/orcl"); pds.setUser("<user>"); pds.setPassword("<password>"); Connection conn = pds.getConnection();
MySQLの例
次の例は、MySQLのConnector/J JDBCドライバを使用した接続の流用を示しています。
PoolDataSource pds = PoolDataSourceFactory.getPoolDataSource(); pds.setConnectionFactoryClassName("com.mysql.cj.jdbc.MysqlDataSource"); pds.setURL("jdbc:mysql://host:3306/dbname"); pds.setUser("<user>"); pds.setPassword("<password>"); Connection conn = pds.getConnection();
3.1.3 プール対応のXAデータソースの使用方法
UCPは、分散トランザクションに参加できるXA接続に使用されるプール対応のXAデータソース(oracle.ucp.jdbc.PoolXADataSource
)を提供します。UCP JDBC XAプールには、非XAのUCP JDBCプールと同じ機能があります。oracle.ucp.jdbc.PoolDataSourceFactory
ファクトリ・クラスは、プール対応のXAデータソース・インスタンスを作成するgetPoolXADataSource()
メソッドを備えています。たとえば:
PoolXADataSource pds = PoolDataSourceFactory.getPoolXADataSource();
プール対応のXAデータソース・インスタンスには、非XAデータソース・インスタンスと同様、実際の物理的な接続を取得するためにコネクション・ファクトリ、URL、ユーザー名およびパスワードが必要です。これらのプロパティは、非XAデータソース・インスタンスと同様の方法(前述参照)で設定されます。しかし、XA接続を取得するには、XA固有のコネクション・ファクトリ・クラスが必要です。通常、XAコネクション・ファクトリはJDBCドライバの一部として提供され、データソースそのものにすることができます。次の例では、JDBCドライバに付属するOracleのoracle.jdbc.xa.client.OracleXADataSource
XAコネクション・ファクトリ・クラスを使用しています。他のベンダーのJDBCドライバを使用している場合は、該当するXAコネクション・ファクトリ・クラスについてベンダーのドキュメントを参照してください。
pds.setConnectionFactoryClassName("oracle.jdbc.xa.client.OracleXADataSource"); pds.setURL("jdbc:oracle:thin:@//localhost:1521/orcl"); pds.setUser("user"); pds.setPassword("password");
最後に、プール対応のXAデータソースは、一連のgetXAConnection
メソッドを備えています。これらのメソッドは、javax.sql.XAConnection
タイプの接続ハンドルをプールから流用するために使用されます。getXAConnection
メソッドは、前述のgetConnection
メソッドと同じです。次の例では、XA接続の流用を示します。
PoolXADataSource pds = PoolDataSourceFactory.getPoolXADataSource(); pds.setConnectionFactoryClassName("oracle.jdbc.xa.client.OracleXADataSource"); pds.setURL("jdbc:oracle:thin:@//localhost:1521/orcl"); pds.setUser("<user>"); pds.setPassword("<password>"); XAConnection conn = pds.getXAConnection();
関連トピック
3.1.4 接続プロパティの設定
Oracleのコネクション・ファクトリでは、特定の機能を使用して接続を構成するプロパティがサポートされます。UCPプール対応のデータソースは、setConnectionProperties(Properties)
メソッドを備えています。このメソッドは、指定されたコネクション・ファクトリにプロパティを設定するために使用されます。次の例では、OracleのJDBCドライバの接続プロパティの設定を示します。他のベンダーのJDBCドライバを使用している場合は、ベンダー固有のドキュメントを参照して、この方法でのプロパティの設定がサポートされているかどうか、またどのプロパティが使用できるかを確認してください。
Properties connProps = new Properties(); connProps.put("fixedString", false); connProps.put("remarksReporting", false); connProps.put("restrictGetTables", false); connProps.put("includeSynonyms", false); connProps.put("defaultNChar", false); connProps.put("AccumulateBatchResult", false); pds.setConnectionProperties(connProps);
UCP JDBC接続プールは、プールの作成後および使用中にsetConnectionProperties
がコールされた場合、作成済の接続を削除しません。
関連項目:
接続を構成するためのサポートされているプロパティの詳細なリストは、Oracle Database JDBC Java APIリファレンスを参照してください。たとえば、自動コミット・モードを設定するには、OracleConnection.CONNECTION_PROPERTY_AUTOCOMMIT
プロパティを使用できます。
3.1.5 JNDIを使用した接続の流用
接続は、プール対応のデータソースのJNDIルックアップを実行し、戻されたオブジェクトでgetConnection()
をコールすることで、接続プールから流用できます。まず、プール対応のデータソースをJNDIコンテキストおよび論理名にバインドする必要があります。これは、オブジェクト参照の登録および検索が可能な、ネーミングおよびディレクトリ・サービス用のサービス・プロバイダ・インタフェース(SPI)をアプリケーションが実装していることを前提とします。
次の例では、Sun社のファイル・システムJNDIサービス・プロバイダを使用しています。このサービス・プロバイダは、次のJNDIソフトウェア・ダウンロード・ページからダウンロードできます。
http://www.oracle.com/technetwork/java/index.html
この例では、初期コンテキストを作成した後、MyPooledDataSource
という名前にバインドされているプール対応のデータソースのルックアップを実行しています。その後、戻されたオブジェクトを使用して接続プールから接続を流用しています。
Hashtable env = new Hashtable(); env.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.fscontext.RefFSContextFactory"); env.put(Context.PROVIDER_URL, "file:/tmp"); ctx = new InitialContext(env); PoolDataSource jpds = (PoolDataSource)ctx.lookup(MyPooledDataSource); Connection conn = jpds.getConnection();
この例では、MyPoolDataSource
をコンテキストにバインドする必要があります。たとえば:
PoolDataSource pds = PoolDataSourceFactory.getPoolDataSource(); pds.setConnectionFactoryClassName("oracle.jdbc.pool.OracleDataSource"); pds.setURL("jdbc:oracle:thin:@//localhost:1521/orcl"); pds.setUser("<user>"); pds.setPassword("<password>"); ctx.bind(MyPooledDataSource, pds);
3.1.6 接続初期化コールバックについて
接続初期化コールバックにより、アプリケーションおよびフレームワークはユニバーサル接続プールから取得される接続を初期化できます。プールからの接続のチェックアウトのたびに、またファイルオーバー中に再接続が成功するたびに、初期化コールバックが実行されます。
次の項で、初期化コールバックについて説明します。
3.1.6.1 接続初期化コールバックの概要
変更できないため、アプリケーションで接続ラベリングを使用しない場合、このようなアプリケーションには接続初期化コールバックが提供されます。
登録されると、接続がプールから流用されるたびに、またリカバリ可能なエラー後に再接続が成功するたびに、初期化コールバックは実行されます。実行時とリプレイ時の両方に同じコールバックを使用すると、元のセッションの確立時に使用されたのとまったく同じ初期化が実行時に確実に再設定されます。コールバックの起動が失敗した場合、リプレイはその接続で無効になります。
3.1.6.2 初期化コールバックの作成
UCP接続初期化コールバックを作成するために、アプリケーションはoracle.ucp.jdbc.ConnectionInitializationCallback
インタフェースを実装しています。このインタフェースには、次のメソッドがあります。
void initialize(java.sql.Connection connection) throws SQLException;
ノート:
-
コールバックは、接続プールごとに1つ作成されます。
-
このコールバックは、ラベリング・コールバックが接続プール用に登録されている場合、使用されません。
例
次の例では、単純な初期化コールバックの作成方法を示します。
import oracle.ucp.jdbc.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) } }
3.1.6.3 初期化コールバックの登録
UCPには、接続初期化コールバックを登録するために、oracle.ucp.jdbc.PoolDataSource
インタフェースにregisterConnectionInitializationCallback
メソッドが用意されています。
public void registerConnectionInitializationCallback (ConnectionInitializationCallback cbk) throws SQLException;
コールバックは、各接続プール・インスタンスに1つ登録できます。
3.1.6.4 初期化コールバックの削除または登録解除
UCPには、接続初期化コールバックを登録解除するために、oracle.ucp.jdbc.PoolDataSource
インタフェースにunregisterConnectionInitializationCallback
メソッドが用意されています。
public void unregisterConnectionInitializationCallback() throws SQLException;
関連項目:
詳細は、『Oracle Universal Connection Pool Java API Reference』を参照してください