JDBC 2 付属の API に、標準の接続プール機能が導入されました。このアドオン API は JDBC 2.0 オプションパッケージまたは JDBC 2.0 標準拡張と呼ばれます。以来、これらの機能はコア JDBC 3 API に含まれています。PostgreSQL JDBC ドライバは、JDK 1.3.x とともに動作する JDBC 2.0 オプションパッケージ (JDBC 2) または JDK 1.4+ (JDBC 3) でこれらの機能をサポートしています。JDBC 2.0 オプションパッケージはほとんどのアプリケーションサーバに組み込まれていますが、Sun の JDBC ダウンロードサイト から個別に入手することも可能です。
JDBC API には、接続プール用のクライアントインタフェースおよびサーバインタフェースが用意されています。クライアントインタフェースは javax.sql.DataSource です。これは通常、アプリケーションコードがプールされたデータベース接続を取得するために使用します。サーバインタフェースは javax.sql.ConnectionPoolDataSource で、ほとんどのアプリケーションサーバはこれを使用して PostgreSQL JDBC とのインタフェースをとります。
アプリケーションサーバ環境では、アプリケーションサーバ構成は通常 PostgreSQL ConnectionPoolDataSource の実装を参照し、アプリケーションコンポーネントコードは通常、アプリケーションサーバ (PostgreSQL ではなく) が提供する DataSource 実装を獲得します。
アプリケーションサーバを使用しない環境では、PostgreSQL は、アプリケーションが直接使用できる DataSource を 2 つ実装しています。1 つの実装が接続プールを実行し、もう 1 つの実装はプールは行わずに DataSource インタフェースを介して単にデータベース接続へのアクセスを提供します。 繰り返しますが、これらの実装は、アプリケーションサーバが ConnectionPoolDataSource インタフェースをサポートしていない場合を除き、アプリケーションサーバ環境で使用すべきではありません 。
PostgreSQL は、JDBC 2 用と JDBC 3 用に ConnectionPoolDataSource をそれぞれ 1 つずつ実装しています。
Table 5-1. ConnectionPoolDataSource 実装
JDBC | 実装クラス |
---|---|
2 | org.postgresql.jdbc2.optional.ConnectionPool |
3 | org.postgresql.jdbc3.Jdbc3ConnectionPool |
どちらの実装も同じ構成スキーマを使用しています。JDBC では ConnectionPoolDataSource を JavaBean プロパティを使用して構成する必要があります。 したがってこれらのプロパティのそれぞれに get メソッドと set メソッドができます。
Table 5-2. ConnectionPoolDataSource 構成プロパティ
プロパティ | 型 | 説明 |
---|---|---|
serverName | String | PostgreSQL データベースサーバのホスト名 |
databaseName | String | PostgreSQL データベース名 |
portNumber | int | PostgreSQL データベースサーバが監視している TCP/IP ポート (デフォルトのポートを使用する場合は 0) |
user | String | データベース接続の作成に使用するユーザ |
password | String | データベース接続の作成に使用するパスワード |
defaultAutoCommit | boolean | 接続が呼び出し元に渡される際に autoCommit (自動コミット) を有効にするか無効にするかを指定。デフォルトは自動コミットを無効にする false です。 |
多くのアプリケーションサーバは、プロパティ形式の構文を使用してこれらのプロパティを構成するので、プロパティをテキストのブロックとして入力することはめずらしくありません。
PostgreSQL は、JDBC 2 用と JDBC 3 用に DataSource をそれぞれ 2 つずつ実装しています。 クライアントが close メソッドを呼び出すと、プールの実装は実際に接続をクローズするのではなく、その接続を使用可能な接続のプールに返して他のクライアントが使用できるようにします。これにより、接続を何度もオープンしクローズすることによるオーバーヘッドをなくすとともに、多数のクライアントが少数のデータベース接続を共有することが可能になります。
このプールデータソース実装は、必ずしも優れた機能を持っているとは言えません。例えば、接続はプール自体がクローズされるまでは決してクローズされないので、プールを縮小することができません。また、デフォルトで構成されたユーザ以外のユーザによって要求された接続はプールされません。多くのアプリケーションサーバではより高度なプール機能を提供しており、代わりに ConnectionPoolDataSource 実装を使用しています。
Table 5-3. DataSource 実装
JDBC | プール | 実装クラス |
---|---|---|
2 | なし | org.postgresql.jdbc2.optional.SimpleDataSource |
2 | あり | org.postgresql.jdbc2.optional.PoolingDataSource |
3 | なし | org.postgresql.jdbc3.Jdbc3SimpleDataSource |
3 | あり | org.postgresql.jdbc3.Jdbc3PoolingDataSource |
すべての実装で同じ構成スキーマを使用しています。JDBC では DataSource を JavaBean プロパティを使用して構成する必要があります。したがってこれらのプロパティのそれぞれに get メソッドと set メソッドができます。
Table 5-4. DataSource 構成プロパティ
プロパティ | 型 | 説明 |
---|---|---|
serverName | String | PostgreSQL データベースサーバのホスト名 |
databaseName | String | PostgreSQL データベース名 |
portNumber | int | PostgreSQL データベースサーバが監視している TCP/IP ポート (デフォルトのポートを使用する場合は 0) |
user | String | データベース接続の作成に使用するユーザ |
password | String | データベース接続の作成に使用するパスワード |
このプール実装に構成プロパティをいくつか追加する必要があります。
Table 5-5. 追加のプール DataSource 構成プロパティ
プロパティ | 型 | 説明 |
---|---|---|
dataSourceName | String | プール DataSource はすべて固有の名前を持つ必要があります |
initialConnections | int | プールの開始時に作成されるデータベース接続数 |
maxConnections | int | 一度にオープンできるデータベース接続の最大数。これより多くの接続が要求されると、接続がプールに返されるまで呼び出し側がハングします。 |
プール DataSource を使用する典型的なアプリケーションコードの例を示します。
Example 5-6. DataSource コード例
プール DataSource を開始するコードの例
Jdbc3PoolingDataSource source = new Jdbc3PoolingDataSource(); source.setDataSourceName("A Data Source"); source.setServerName("localhost"); source.setDatabaseName("test"); source.setUser("testuser"); source.setPassword("testpassword"); source.setMaxConnections(10);
プールに入っている接続を使用するためのコードの例を以下に示します。接続を閉じた状態にしておくことが重要です。開いているとプールは接続をリークし、最終的にすべてのクライアントをロックアウトします。
Connection con = null; try { con = source.getConnection(); // 接続を使用する } catch(SQLException e) { // エラーをログに記録 } finally { if(con != null) { try {con.close();}catch(SQLException e) {} } }
ConnectionPoolDataSource および DataSource の実装はすべて、JNDI に格納することができます。.非プール実装の場合、JNDI からオブジェクトが抽出される度に、格納済みのインスタンスと同じ設定の新しいインスタンスが作成されます。プール実装については、同じインスタンスが使用可能であればそのインスタンスが抽出され (異なる JVM が JNDI からプールを抽出するのではなく) 、使用可能でない場合は、同じ設定で新しいインスタンスが作成されます。
アプリケーションサーバ環境では、アプリケーションサーバの DataSource インスタンスは通常 PostgreSQL ConnectionPoolDataSource 実装ではなく、JNDI に格納されます。
アプリケーション環境では、アプリケーションは JNDI に DataSource を格納する場合があります。こうすることにより、アプリケーションは、DataSource への参照をこれを使用するすべてのアプリケーションコンポーネントに対して使用可能にする必要がなくなります。
Example 5-7. DataSource JNDI コード例
プール DataSource を初期化して JNDI に追加するアプリケーションコードの例を以下に示します。
Jdbc3PoolingDataSource source = new Jdbc3PoolingDataSource(); source.setDataSourceName("A Data Source"); source.setServerName("localhost"); source.setDatabaseName("test"); source.setUser("testuser"); source.setPassword("testpassword"); source.setMaxConnections(10); new InitialContext().rebind("DataSource", source);
プールに入っている接続を使用するためのコードの例を以下に示します。
Connection con = null; try { DataSource source = (DataSource)new InitialContext().lookup("DataSource"); con = source.getConnection(); // 接続を使用する } catch(SQLException e) { // エラーをログに記録 } catch(NamingException e) { // DataSource wasn't found in JNDI } finally { if(con != null) { try {con.close();}catch(SQLException e) {} } }