この章の内容は次のとおりです。
アプリケーションは、プール対応のデータソースを使用して接続を流用します。UCP for JDBC APIは、2つのプール対応のデータソースを備えています。1つは標準接続を流用するためのものであり、もう1つはXA接続を流用するためのものです。これらのデータソースは、UCP JDBC接続プール機能にアクセスでき、接続の流用に使用される一連のgetConnection
メソッドを備えています。XAと非XAのどちらのUCP JDBC接続プールにも同じプール機能があります。
UCP JDBC接続プールは、使用可能な接続と流用された接続の両方を保持します。アプリケーションが使用可能な接続と一致する接続の流用をリクエストすると、プールの接続が再利用されます。プール内の使用可能な接続がリクエストされた接続と一致しない場合は、新しい接続が作成されます。使用可能な接続と流用された接続の数は、プール・サイズ、タイムアウト間隔および検証ルールなどのプールのプロパティによって異なります。
この項では、次の概念について説明します。
注意: この項の説明では、プール対応のデータソースを使用して接続プールを暗黙的に作成および起動します。接続プール・マネージャを使用した接続プールの明示的な作成方法は、第7章「接続プール・マネージャの使用方法」を参照してください。 |
UCP for JDBCには、データベースへの接続の取得に使用されるプール対応のデータソース(oracle.ucp.jdbc.PoolDataSource
)があります。oracle.ucp.jdbc.PoolDataSourceFactory
ファクトリ・クラスは、プール対応のデータソース・インスタンスを作成するgetPoolDataSource()
メソッドを備えています。次に例を示します。
PoolDataSource pds = PoolDataSourceFactory.getPoolDataSource();
プール対応のデータソースには、実際の物理的な接続を取得するためにコネクション・ファクトリ・クラスが必要です。通常、コネクション・ファクトリはJDBCドライバの一部として提供され、データソースそのものにすることができます。UCP JDBC接続プールでは任意のJDBCドライバを使用して物理接続を作成することができ、作成した接続はプールで管理されます。setConnectionFactoryClassName(String)
メソッドは、プール対応のデータソース・インスタンスにコネクション・ファクトリを定義するために使用されます。次の例では、JDBCドライバに付属するOracleのoracle.jdbc.pool.OracleDataSource
コネクション・ファクトリ・クラスを使用しています。他のベンダーのJDBCドライバを使用している場合は、該当するコネクション・ファクトリ・クラスについてベンダーのドキュメントを参照してください。
pds.setConnectionFactoryClassName("oracle.jdbc.pool.OracleDataSource");
コネクション・ファクトリ・クラスに加えて、プール対応のデータソースには、データベースへの接続に使用されるURL、ユーザー名およびパスワードが必要です。プール対応のデータソース・インスタンスは、これらの各プロパティを設定するメソッドを備えています。次の例では、Oracle JDBC Thinドライバの構文を使用しています。他のベンダーのJDBCドライバを使用している場合は、使用する適切なURL構文についてベンダーのドキュメントを参照してください。
pds.setURL("jdbc:oracle:thin:@//localhost:1521/XE"); pds.setUser("user"); pds.setPassword("password");
注意: Oracle URL構文の使用方法は、『Oracle Database JDBC開発者ガイド』を参照してください。 |
最後に、プール対応のデータソースは、一連のgetConnection
メソッドを備えています。メソッドには次のものがあります。
getConnection()
: データベースへの接続に使用されたユーザー名およびパスワードと関連付けられている接続を戻します。
getConnection(String username, String password)
: 指定されたユーザー名およびパスワードと関連付けられている接続を戻します。
getConnection(java.util.Properties labels)
: 指定されたラベルと一致する接続を戻します。接続ラベルの使用方法は、第5章「UCPでの接続のラベル付け」を参照してください。
getConnection(String username, String password, java.util.Properties labels)
: 指定されたユーザー名およびパスワードと関連付けられ、指定されたラベルと一致する接続を戻します。接続ラベルの使用方法は、第5章「UCPでの接続のラベル付け」を参照してください。
アプリケーションは、getConnection
メソッドを使用して、java.sql.Connection
タイプの接続ハンドルをプールから流用します。リクエストされた接続と一致する(同じURL、ユーザー名およびパスワード)接続ハンドルがすでにプール内に存在する場合は、その接続ハンドルがアプリケーションに戻されます。存在しない場合は、新しい接続が作成され、新しい接続ハンドルがアプリケーションに戻されます。OracleとMySQLの両方の例を示します。
Oracleの例
次の例では、JDBC Thinドライバを使用する場合の接続の流用を示します。
PoolDataSource pds = PoolDataSourceFactory.getPoolDataSource(); pds.setConnectionFactoryClassName("oracle.jdbc.pool.OracleDataSource"); pds.setURL("jdbc:oracle:thin:@//localhost:1521/XE"); pds.setUser("<user>"); pds.setPassword("<password>"); Connection conn = pds.getConnection();
MySQLの例
次の例では、MySQLのConnector/J JDBCドライバを使用する場合の接続の流用を示します。
PoolDataSource pds = PoolDataSourceFactory.getPoolDataSource(); pds.setConnectionFactoryClassName("com.mysql.jdbc.jdbc2.optional.
MysqlDataSource"); pds.setURL("jdbc:mysql://host:3306/dbname"); pds.setUser("<user>"); pds.setPassword("<password>"); Connection conn = pds.getConnection();
UCP for JDBCには、プール対応のXAデータソース(oracle.ucp.jdbc.PoolXADataSource
)があります。これは、分散トランザクションに参加できるXA接続の取得に使用されます。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/XE"); 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/XE"); pds.setUser("<user>"); pds.setPassword("<password>"); XAConnection conn = pds.getXAConnection();
Oracleのコネクション・ファクトリでは、特定の機能を使用して接続を構成するプロパティがサポートされます。UCP for JDBCプール対応のデータソースは、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 プロパティを使用できます。 |
接続は、プール対応のデータソースの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/XE"); pds.setUser("<user>"); pds.setPassword("<password>"); ctx.bind(MyPooledDataSource, pds);
このコールバックにより、アプリケーションおよびフレームワークはユニバーサル接続プールから取得される接続を初期化できます。プールからの接続のチェックアウトのたびに、またファイルオーバー中に再接続が成功するたびに、初期化コールバックが実行されます。
変更できないため、アプリケーションで接続ラベリングを使用しない場合、このようなアプリケーションには接続初期化コールバックが提供されます。
登録されると、接続がプールから流用されるたびに、またリカバリ可能なエラー後に再接続が成功するたびに、初期化コールバックは実行されます。実行時とリプレイ時の両方に同じコールバックを使用すると、元のセッションの確立時に使用されたのとまったく同じ初期化が実行時に確実に再設定されます。コールバックの起動が失敗した場合、リプレイはその接続で無効になります。
次の項で、初期化コールバックについて説明します。
UCP接続初期化コールバックを作成するために、アプリケーションはoracle.ucp.jdbc.ConnectionInitializationCallback
インタフェースを実装しています。このインタフェースには、次のメソッドがあります。
void initialize(java.sql.Connection connection) throws SQLException;
注意:
|
例
次の例では、単純な初期化コールバックの作成方法を示します。
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) } }
UCPには、接続初期化コールバックを登録するために、oracle.ucp.jdbc.PoolDataSource
インタフェースにregisterConnectionInitializationCallback
メソッドが用意されています。
public void registerConnectionInitializationCallback (ConnectionInitializationCallback cbk) throws SQLException;
コールバックは、各接続プール・インスタンスに1つ登録できます。
UCPには、接続初期化コールバックを登録解除するために、oracle.ucp.jdbc.PoolDataSource
インタフェースにunregisterConnectionInitializationCallback
メソッドが用意されています。
public void unregisterConnectionInitializationCallback (ConnectionInitializationCallback cbk) throws SQLException;
関連項目: 詳細は、Oracle Universal Connection Pool for JDBC Java APIリファレンスを参照してください |
UCP JDBC接続プールは、接続プールのプロパティを使用して構成します。プロパティには、プール対応のデータソース・インスタンスで使用可能なget
メソッドとset
メソッドがあります。これらのメソッドは、プールをプログラムで構成するための便利な手段です。プールのプロパティが設定されていない場合、接続プールはデフォルトのプロパティ値を使用します。
次の例では、接続プールのプロパティの構成を示します。この例では、接続プール名およびプールで許容される最大/最小接続数を設定しています。サポートされる全プロパティとそのデフォルト値の詳細は、第4章「ユニバーサル接続プールの動作の最適化」を参照してください。
PoolDataSource pds = PoolDataSourceFactory.getPoolDataSource(); pds.setConnectionPoolName("JDBC_UCP"); pds.setMinPoolSize(4);pds.setMaxPoolSize(20);
UCP JDBC接続プールのプロパティは任意の順序で設定できます。また、実行時に動的に変更できます。たとえば、setMaxPoolSize
はいつでも変更できます。プールはその新しい値を認識し、その値に適応します。
接続は、接続の流用時にプールのプロパティを使用して検証できます。また、ValidConnection
インタフェースを使用してプログラムで検証することもできます。この項では、これら2つの方法について詳しく説明します。無効な接続は、アプリケーションのパフォーマンスおよび可用性に影響を及ぼす可能性があります。
接続プールから接続を流用する際に、接続に対してSQL文を実行することで、接続を検証できます。接続の検証を有効にするには、次の2つの接続プールのプロパティを組み合せて使用します。
setValidateConnectionOnBorrow(boolean)
: 接続プールから接続を流用する際に、接続を検証するかどうかを指定します。このメソッドにより、プールから流用されるすべての接続に対して検証が有効になります。false
値は、検証を実行しないことを意味します。デフォルト値はfalse
です。
setSQLForValidateConnection(String)
: プールから接続を流用する際に、接続に対して実行されるSQL文を指定します。
注意: setSQLForValidateConnection プロパティは、Oracle JDBCドライバを使用している場合には使用しないでください。Oracle JDBCドライバを使用している場合、UCP for JDBCは内部pingを実行します。このメカニズムはSQL文の実行よりも高速ですが、このプロパティを設定すると上書きされます。かわりに、setSQLForValidateConnection プロパティを使用せずに、setValidateConnectionOnBorrow プロパティをtrue に設定してください。 |
次の例では、プールから接続を流用する際の接続の検証を示します。この例では、MySQLのConnector/J JDBCドライバを使用しています。
PoolDataSource pds = PoolDataSourceFactory.getPoolDataSource(); pds.setConnectionFactoryClassName("com.mysql.jdbc.jdbc2.optional.
MysqlDataSource"); pds.setURL("jdbc:mysql://host:3306/mysql"); pds.setUser("<user>"); pds.setPassword("<password>"); pds.setValidateConnectionOnBorrow(true); pds.setSQLForValidateConnection("select * from mysql.user"); Connection conn = pds.getConnection();
oracle.ucp.jdbc.ValidConnection
インタフェースは、2つのメソッドisValid
およびsetInvalid
を備えています。isValid
メソッドは接続が使用可能かどうかを戻し、setInvalid
メソッドはプール・インスタンスから接続を削除する必要があることを示すために使用されます。setInvalid
メソッドの使用方法は、「UCPからの接続の削除」を参照してください。
isValid
メソッドは、SQL例外がスローされた後でも接続が使用可能かどうかをチェックするために使用されます。また、いつでも流用された接続が有効であるかどうかをチェックするために使用できます。このメソッドは、Oracle RAC停止イベント後にトリガーされる高速接続フェイルオーバー・アクションなどの再試行メカニズムと組み合せると、特に便利です。高速接続フェイルオーバーの詳細は、第8章「Oracle RAC機能の使用方法」を参照してください。
注意: isValid メソッドは、プール・インスタンスおよびOracle JDBCドライバを調べて、接続がまだ有効かどうかを判断します。プールとドライバの両方で接続がまだ有効であることがレポートされた場合にかぎり、isValid メソッドによってデータベースへのラウンドトリップが発生します。このラウンドトリップを使用して、プールまたはドライバですぐには検出されないデータベース障害がないかをチェックします。 |
また、isValid
メソッドは、接続タイムアウト機能および接続獲得機能と組み合せて使用しても便利です。これらの機能は、アプリケーションで接続がまだ保持されているときに、接続をプールに返すことができます。このような場合、isValid
メソッドはfalse
を戻し、アプリケーションが新しい接続を取得できるようにします。
次の例では、isValid
メソッドの使用方法を示します。
try { conn = poolDataSouorce.getConnection ...}catch (SQLException sqlexc) { if (conn == null || !((ValidConnection) conn).isValid()) // take the appropriate action ... conn.close(); }
XAアプリケーションでは、isValid()
メソッドをコールする前に、PoolXADataSource
から取得されるXAConnection
をValidConnection
にキャストする必要があります。XAConnection.getConnection()
メソッドをコールして取得されるConnection
をValidConnecion
にキャストすると、例外がスローされることがあります。
流用された接続のうち、もう使用しないものはプールに返して、次の接続リクエストで使用できるようにする必要があります。close
メソッドにより、接続をクローズしてプールに自動的に返します。close
メソッドは、プールから接続を物理的に削除しません。
クローズしない場合、流用された接続は流用されたままになります。つまり、使用可能な接続がない場合に、後続の接続リクエストによって新しい接続が作成されます。この動作は、多くの接続が作成される原因となり、システム・パフォーマンスに影響を及ぼす可能性があります。
次の例では、接続のクローズおよびプールへの返却を示します。
Connection conn = pds.getConnection(); //do some work with the connection. conn.close(); conn=null;
ValidConnection
インタフェースのsetInvalid
メソッドは、接続のクローズ時に、接続プールから接続を削除する必要があることを示します。通常、このメソッドは、例外の後やValidConnection
インタフェースのisValid
メソッドがfalse
を戻した場合など、接続が使用できなくなったときに使用されます。また、接続の状態が悪いとアプリケーションが判断した場合にも使用できます。次の例では、setInvalid
メソッドを使用した接続のクローズおよびプールからの削除を示します。
Connection conn = pds.getConnection(); ... ((ValidConnection) conn).setInvalid(); ... conn.close(); conn=null;
ミドルウェア・プラットフォームやフレームワークなどのサード・パーティ製品では、UCPを使用してアプリケーションおよびサービスに接続プーリング機能を提供できます。UCP統合には、スタンドアロン・アプリケーションで使用できるものと同じ接続プール機能があり、Oracle Databaseとの緊密な統合を提供します。
2つのデータソース・クラスPoolDataSourceImpl
(非XA接続プール用)とPoolXADataSourceImpl
(XA接続プール用)が、UCPとの統合点として使用できます。どちらのクラスもoracle.ucp.jdbc
パッケージにあります。これらのクラスは、それぞれPoolDataSource
インタフェースおよびPoolXADataSource
インタフェースの実装で、デフォルトのコンストラクタがあります。実装クラスの詳細は、『Oracle Universal Connection Pool Java API Reference』を参照してください。
これらの実装では、接続プール・インスタンスを明示的に作成し、接続を返すことができます。次に例を示します。
PoolXADataSource pds = new PoolXADataSourceImpl(); pds.setConnectionFactoryClassName("oracle.jdbc.xa.client.OracleXADataSource"); pds.setURL("jdbc:oracle:thin:@//localhost:1521/XE"); pds.setUser("user"); pds.setPassword("password"); XAConnection conn = pds.getXAConnection();
サード・パーティ製品では、これらのデータソース実装クラスをインスタンス化できます。また、これらのインタフェースのメソッドは、JavaBean設計パターンに準拠しているため、リフレクションを使用して接続プールのプロパティをクラスに設定するために使用できます。たとえば、Oracle JDBCコネクション・ファクトリおよびデータベースを使用するUCPデータソースは、次のように定義して、JNDIレジストリにロードできます。
<data-sources> <data-source name="UCPDataSource" jndi-name="jdbc/UCP_DS" data-source-class="oracle.ucp.jdbc.PoolDataSourceImpl"> <property name="ConnectionFactoryClassName" value="oracle.jdbc.pool.OracleDataSource"/> <property name="URL" value="jdbc:oracle:thin:@//localhost:1521:oracle"/> <property name="User" value"user"/> <property name="Password" value="password"/> <property name="ConnectionPoolName" value="MyPool"/> <property name="MinPoolSize" value="5"/> <property name="MaxPoolSize" value="50"/> </data-source> </data-sources>
リフレクションを使用する場合、name属性はプロパティの設定に使用されるsetterメソッドの名前(大/小文字を区別)と一致します。つまり、次のようにして、アプリケーションでデータソースを使用できます。
Connection connection = null; try { InitialContext context = new InitialContext(); DataSource ds = (DataSource) context.lookup( "jdbc/UCP_DS" ); connection = ds.getConnection(); ...