6.7. JDBC 接続プールの使用

本セクションでは、JDBC 接続プールの使用の概要と、以下の接続プールモジュールの使用方法を説明します。

重要

本章では、データソース管理の内部に関する包括的な情報を紹介しています。DBCP2 接続プール機能に関する情報が提供されていますが、この接続プールには適切な JTA 参加機能がありますが、XA リカバリー の機能はないので注意してください。

XA リカバリー が有効であることを確認するには、pax-jdbc-pool-transx または pax-jdbc-pool-narayana 接続プールモジュールを使用します。

6.7.1. JDBC 接続プールの使用について

以前の例では、データベース固有のデータソース ファクトリー を登録する方法を説明しました。データソース 自体は接続のファクトリーであるため、org.osgi.service.jdbc.DataSourceFactory は 3 種類のデータソースを生成できるメタファクトリー として扱われる可能性があります (さらに java.sql.Driver)。

  • javax.sql.DataSource
  • javax.sql.ConnectionPoolDataSource
  • javax.sql.XADataSource

たとえば、pax-jdbc-mysql は、以下を作成する org.ops4j.pax.jdbc.mysql.impl.MysqlDataSourceFactory を登録します。

  • javax.sql.DataSourcecom.mysql.jdbc.jdbc2.optional.MysqlDataSource
  • javax.sql.ConnectionPoolDataSourcecom.mysql.jdbc.jdbc2.optional.MysqlConnectionPoolDataSource
  • javax.sql.XADataSourcecom.mysql.jdbc.jdbc2.optional.MysqlXADataSource
  • java.sql.Drivercom.mysql.jdbc.Driver

PostgreSQL ドライバー自体は OSGi JDBC サービスを実装し、以下を生成します。

  • javax.sql.DataSourceorg.postgresql.jdbc2.optional.PoolingDataSource (プール関連のプロパティーが指定されている場合) または org.postgresql.jdbc2.optional.SimpleDataSource
  • javax.sql.ConnectionPoolDataSourceorg.postgresql.jdbc2.optional.ConnectionPool
  • javax.sql.XADataSourceorg.postgresql.xa.PGXADataSource
  • java.sql.Driverorg.postgresql.Driver

標準の DataSource 例 に記載されているように、JTA 環境で機能する場合は、プーリング汎用 データソースは、(XA) 接続を実際に取得するには データベース固有 のデータソースが必要です。

すでに後者があるので、実際の信頼性がある、汎用接続プールが必要です。

標準の DataSource 例 は、データベース固有のデータソースを使用して汎用プールを設定する方法を示しています。pax-jdbc-pool-* バンドルは上記の org.osgi.service.jdbc.DataSourceFactory サービスとスムーズに連携します。

OSGI Enterprise R6 JDBC 仕様が org.osgi.service.jdbc.DataSourceFactory 標準インターフェイスを提供するのと同じように、pax-jdbc-pool-commonプロプライエタリーの org.ops4j.pax.jdbc.pool.common.PooledDataSourceFactory インターフェイスを提供します。

public interface PooledDataSourceFactory {

    javax.sql.DataSource create(org.osgi.service.jdbc.DataSourceFactory dsf, Properties config)

}

このインターフェイスは、以前に提示されたこの重要なメモに完全に準拠しており、繰り返す価値があります。

重要

アプリケーションが XA トランザクションや接続プーリングを使用する場合でも、アプリケーションは他の 2 つの JDBC データソースインターフェイスではなく、javax.sql.DataSource と対話します。

このインターフェイスは、データベース固有の非プーリングデータからプーリングデータソースを作成するだけです。また、これは データソースファクトリー(メタファクトリー) で、データベース固有のデータソースのファクトリーをデータソースのプーリングファクトリーに変換します。

注記

javax.sql.DataSource オブジェクトのプールをすでに返している org.osgi.service.jdbc.DataSourceFactory サービスを使用して、アプリケーションで javax.sql.DataSource オブジェクトのプーリングが設定されないようにすることはできません。

以下の表は、プールされたデータソースファクトリーを登録するバンドルを示しています。この表では、o.o.p.j.p のインスタンスは org.ops4j.pax.jdbc.pool を表します。

バンドルPooledDataSourceFactoryプールキー

pax-jdbc-pool-narayana

o.o.p.j.p.narayana.impl.Dbcp(XA)PooledDataSourceFactory

narayana

pax-jdbc-pool-dbcp2

o.o.p.j.p.dbcp2.impl.Dbcp(XA)PooledDataSourceFactory

dbcp2

pax-jdbc-pool-transx

o.o.p.j.p.transx.impl.Transx(Xa)PooledDataSourceFactory

transx

上記のバンドルはデータソースファクトリーのみをインストールし、データソース自体にはインストールしません。アプリケーションは javax.sql.DataSource create(org.osgi.service.jdbc.DataSourceFactory dsf, Properties config) メソッドを呼び出す何かが必要です。

6.7.2. dbcp2 接続プールモジュールの使用

一般的なデータソースのセクションでは、Apache Commons DBCP モジュール を使用し、設定する方法の例 を紹介します。ここでは、Fuse OSGi 環境で設定方法を説明します。

「PAX-JDBC 設定サービス」 バンドルについて見てみましょう。以下を追跡するだけでなく、ほかも追跡します。

  • org.osgi.service.jdbc.DataSourceFactory services
  • org.ops4j.datasource factory PIDs

このバンドルは、pax-jdbc-pool-* バンドルのいずれかによって登録された org.ops4j.pax.jdbc.pool.common.PooledDataSourceFactory のインスタンスも追跡します。

ファクトリー設定pool プロパティーが含まれる場合、pax-jdbc-config バンドルによって登録される最終データソースはデータベース固有のデータソースになりますが、pool=dbcp2 の場合は以下のいずれかの内部でラッピングされます。

  • org.apache.commons.dbcp2.PoolingDataSource
  • org.apache.commons.dbcp2.managed.ManagedDataSource

これは、一般的なデータソースの例 と同じです。pool プロパティーと、非 xa または xa データソースを選択するブール値 xa プロパティーの他に、org.ops4j.datasource ファクトリー PID接頭辞 が付いたプロパティーが含まれることがあります。

  • pool.*
  • factory.*

各プロパティーが使用される場所は、使用される pax-jdbc-pool-* バンドルによって異なります。DBCP2 の場合は以下のようになります。

  • pool.*: org.apache.commons.pool2.impl.GenericObjectPoolConfig の bean プロパティー (xa と xa 以外の両方)
  • factory.*: org.apache.commons.dbcp2.managed.PoolableManagedConnectionFactory (xa) または org.apache.commons.dbcp2.PoolableConnectionFactory (xa 以外) の Bean プロパティー

6.7.2.1. BasicDataSource の設定プロパティー

以下の表は、BasicDataSource の汎用設定プロパティーを示しています。

パラメーターデフォルト説明

username

 

接続を確立するために JDBC ドライバーに渡される接続ユーザー名。

password

 

接続を確立するために JDBC ドライバーに渡される接続パスワード。

url

 

接続を確立するために JDBC ドライバーに渡される接続 URL。

driverClassName

 

使用する JDBC ドライバーの完全修飾 Java クラス名。

initialSize

0

プールの開始時に作成される接続の初期数。

maxTotal

8

このプールから同時に割り当てることができるアクティブな接続の最大数、または制限なしの場合は負の数。

maxIdle

8

追加の接続が解放されることなく、プール内でアイドル状態を維持できる接続の最大数、または無制限の場合は負の接続。

minIdle

0

追加の接続を作成せずにプール内でアイドル状態を維持できる接続の最小数、または作成しない場合はゼロ。

maxWaitMillis

無期限

例外を出力する前に接続が返されるまでプールが待機する最大ミリ秒数 (使用可能な接続がない場合)、または無期限に待機する場合は -1。

validationQuery

 

呼び出し元に接続を返す前に、このプールからの接続を検証するために使用される SQL クエリー。指定されている場合、このクエリーは、SQL SELECT ステートメントであり、最低でも 1 行を返す必要があります。指定のない場合は、isValid() メソッドを呼び出して接続が検証されます。

validationQueryTimeout

タイムアウトなし

接続検証クエリーが失敗するまでのタイムアウト時間 (秒単位)。正の値に設定されている場合、この値は、検証クエリーの実行に使用されるステートメントの setQueryTimeout メソッドを介してドライバーに渡されます。

testOnCreate

false

作成後にオブジェクトが検証されるかどうか。オブジェクトの検証に失敗した場合には、オブジェクトの作成をトリガーした borrow の試行に失敗します。

testOnBorrow

true

プールからオブジェクトを借りる前に、オブジェクトを検証するかどうか。オブジェクトが検証に失敗すると、プールから破棄され、別のオブジェクトの借用を試みます。

testOnReturn

false

プールへ返す前にオブジェクトが検証されるかどうか。

testWhileIdle

false

アイドルオブジェクトのエビクターによってオブジェクトが検証されるかどうか (ある場合)。オブジェクトが検証できない場合には、プールからオブジェクトは削除されます。

timeBetweenEvictionRunsMillis

-1

アイドルオブジェクトのエビクタースレッドを次に実行するまでの間でどれだけ待機してからスリープするか (ミリ秒単位)。正の値以外の場合は、アイドル状態のオブジェクトのエビクタースレッドは実行されません。

numTestsPerEvictionRun

3

アイドルオブジェクトのエビクタースレッド (ある場合) のそれぞれの実行時に検査するオブジェクトの数。

minEvictableIdleTimeMillis

1000 * 60 * 30

アイドルオブジェクトのエビクターの対象となるまでにオブジェクトがプールでアイドル状態で待機できる最小時間 (ある場合)。

6.7.2.2. DBCP2 プールの設定方法の例

以下は、jdbc. が接頭辞として付けられたプロパティーと便利な構文を使用する DBCP2 プールの設定 (org.ops4j.datasource-mysqlファクトリー PID) の現実的な例です (useSSL=false を除く)。

# Configuration for pax-jdbc-config to choose and configure specific org.osgi.service.jdbc.DataSourceFactory
dataSourceName = mysqlds
dataSourceType = DataSource
osgi.jdbc.driver.name = mysql
jdbc.url = jdbc:mysql://localhost:3306/reportdb
jdbc.user = fuse
jdbc.password = fuse
jdbc.useSSL = false

# Hints for pax-jdbc-config to use org.ops4j.pax.jdbc.pool.common.PooledDataSourceFactory
pool = dbcp2
xa = false

# dbcp2 specific configuration of org.apache.commons.pool2.impl.GenericObjectPoolConfig
pool.minIdle = 10
pool.maxTotal = 100
pool.initialSize = 8
pool.blockWhenExhausted = true
pool.maxWaitMillis = 2000
pool.testOnBorrow = true
pool.testWhileIdle = false
pool.timeBetweenEvictionRunsMillis = 120000
pool.evictionPolicyClassName = org.apache.commons.pool2.impl.DefaultEvictionPolicy

# dbcp2 specific configuration of org.apache.commons.dbcp2.PoolableConnectionFactory
factory.maxConnLifetimeMillis = 30000
factory.validationQuery  = select schema_name from information_schema.schemata
factory.validationQueryTimeout = 2

上記の設定では、poolxa キーは ヒント (サービスフィルタープロパティー) で、登録された org.ops4j.pax.jdbc.pool.common.PooledDataSourceFactory サービスのいずれかを選択します。DBCP2 の場合は以下のようになります。

karaf@root()> feature:install pax-jdbc-pool-dbcp2

karaf@root()> bundle:services -p org.ops4j.pax.jdbc.pool.dbcp2

OPS4J Pax JDBC Pooling DBCP2 (230) provides:
--------------------------------------------
objectClass = [org.ops4j.pax.jdbc.pool.common.PooledDataSourceFactory]
pool = dbcp2
service.bundleid = 230
service.id = 337
service.scope = singleton
xa = false
-----
objectClass = [org.ops4j.pax.jdbc.pool.common.PooledDataSourceFactory]
pool = dbcp2
service.bundleid = 230
service.id = 338
service.scope = singleton
xa = true

以下は、前の例 に接続プール設定を追加した完全な例です。繰り返しになりますが、これは、Fuse の新規インストールから開始していることを前提としています。

  1. JDBC ドライバーをインストールします。

    karaf@root()> install -s mvn:mysql/mysql-connector-java/5.1.34
    Bundle ID: 223
  2. jdbcpax-jdbc-mysql および pax-jdbc-pool-dbcp2 機能をインストールします。

    karaf@root()> feature:repo-add mvn:org.ops4j.pax.jdbc/pax-jdbc-features/1.3.0/xml/features-gpl
    Adding feature url mvn:org.ops4j.pax.jdbc/pax-jdbc-features/1.3.0/xml/features-gpl
    
    karaf@root()> feature:install jdbc pax-jdbc-mysql pax-jdbc-pool-dbcp2
    
    karaf@root()> service:list org.osgi.service.jdbc.DataSourceFactory
    ...
    [org.osgi.service.jdbc.DataSourceFactory]
    -----------------------------------------
     osgi.jdbc.driver.class = com.mysql.jdbc.Driver
     osgi.jdbc.driver.name = mysql
     service.bundleid = 232
     service.id = 328
     service.scope = singleton
    Provided by :
     OPS4J Pax JDBC MySQL Driver Adapter (232)
    
    karaf@root()> service:list org.ops4j.pax.jdbc.pool.common.PooledDataSourceFactory
    [org.ops4j.pax.jdbc.pool.common.PooledDataSourceFactory]
    --------------------------------------------------------
     pool = dbcp2
     service.bundleid = 233
     service.id = 324
     service.scope = singleton
     xa = false
    Provided by :
     OPS4J Pax JDBC Pooling DBCP2 (233)
    
    [org.ops4j.pax.jdbc.pool.common.PooledDataSourceFactory]
    --------------------------------------------------------
     pool = dbcp2
     service.bundleid = 233
     service.id = 332
     service.scope = singleton
     xa = true
    Provided by :
     OPS4J Pax JDBC Pooling DBCP2 (233)
  3. ファクトリー設定 を作成します。

    karaf@root()> config:edit --factory --alias mysql org.ops4j.datasource
    karaf@root()> config:property-set osgi.jdbc.driver.name mysql
    karaf@root()> config:property-set dataSourceName mysqlds
    karaf@root()> config:property-set dataSourceType DataSource
    karaf@root()> config:property-set jdbc.url jdbc:mysql://localhost:3306/reportdb
    karaf@root()> config:property-set jdbc.user fuse
    karaf@root()> config:property-set jdbc.password fuse
    karaf@root()> config:property-set jdbc.useSSL false
    karaf@root()> config:property-set pool dbcp2
    karaf@root()> config:property-set xa false
    karaf@root()> config:property-set pool.minIdle 2
    karaf@root()> config:property-set pool.maxTotal 10
    karaf@root()> config:property-set pool.blockWhenExhausted true
    karaf@root()> config:property-set pool.maxWaitMillis 2000
    karaf@root()> config:property-set pool.testOnBorrow true
    karaf@root()> config:property-set pool.testWhileIdle alse
    karaf@root()> config:property-set pool.timeBetweenEvictionRunsMillis 120000
    karaf@root()> config:property-set factory.validationQuery 'select schema_name from information_schema.schemata'
    karaf@root()> config:property-set factory.validationQueryTimeout 2
    karaf@root()> config:update
  4. pax-jdbc-config が設定を処理して javax.sql.DataSource サービスに指定しているかどうかを確認します。

    karaf@root()> service:list javax.sql.DataSource
    [javax.sql.DataSource]
    ----------------------
     dataSourceName = mysqlds
     dataSourceType = DataSource
     factory.validationQuery = select schema_name from information_schema.schemata
     factory.validationQueryTimeout = 2
     felix.fileinstall.filename = file:${karaf.etc}/org.ops4j.datasource-mysql.cfg
     jdbc.password = fuse
     jdbc.url = jdbc:mysql://localhost:3306/reportdb
     jdbc.user = fuse
     jdbc.useSSL = false
     osgi.jdbc.driver.name = mysql
     osgi.jndi.service.name = mysqlds
     pax.jdbc.managed = true
     pool.blockWhenExhausted = true
     pool.maxTotal = 10
     pool.maxWaitMillis = 2000
     pool.minIdle = 2
     pool.testOnBorrow = true
     pool.testWhileIdle = alse
     pool.timeBetweenEvictionRunsMillis = 120000
     service.bundleid = 225
     service.factoryPid = org.ops4j.datasource
     service.id = 338
     service.pid = org.ops4j.datasource.fd7aa3a1-695b-4342-b0d6-23d018a46fbb
     service.scope = singleton
    Provided by :
     OPS4J Pax JDBC Config (225)
  5. データソースを使用します。

    karaf@root()> jdbc:query mysqlds 'select * from incident'
    date                  │ summary    │ name   │ details                       │ id │ email
    ──────────────────────┼────────────┼────────┼───────────────────────────────┼────┼─────────────────
    2018-02-20 08:00:00.0 │ Incident 1 │ User 1 │ This is a report incident 001 │ 1  │ user1@redhat.com
    2018-02-20 08:10:00.0 │ Incident 2 │ User 2 │ This is a report incident 002 │ 2  │ user2@redhat.com
    2018-02-20 08:20:00.0 │ Incident 3 │ User 3 │ This is a report incident 003 │ 3  │ user3@redhat.com
    2018-02-20 08:30:00.0 │ Incident 4 │ User 4 │ This is a report incident 004 │ 4  │ user4@redhat.com

6.7.3. narayana 接続プールモジュールの使用

pax-jdbc-pool-narayna モジュールはほぼすべてが pax-jdbc-pool-dbcp2 として行われます。XA および XA 以外のシナリオ向けに DBCP2 固有の org.ops4j.pax.jdbc.pool.common.PooledDataSourceFactory をインストールします。唯一 の違いは、XA のシナリオでは追加の統合ポイントがあることです。org.jboss.tm.XAResourceRecovery OSGi サービスは、Narayana トランザクションマネージャーに含まれる com.arjuna.ats.arjuna.recovery.RecoveryManager で取得されるように登録されます。

6.7.4. transx 接続プールモジュールの使用

pax-jdbc-pool-transx バンドルは、org.ops4j.pax.jdbc.pool.common.PooledDataSourceFactory サービスの実装を pax-transx-jdbc バンドルをもとにします。pax-transx-jdbc バンドルは、org.ops4j.pax.transx.jdbc.ManagedDataSourceBuilder 機能を使用して javax.sql.DataSource プールを作成します。これは JCA(Java™ Connector Architecture) ソリューションで、 で説明します。