連載
» 2011年11月07日 00時00分 公開

Tomcat 7の新機能で何ができるようになるのか?(番外編):Commons DBCPを超えるTomcat JDBC Poolとは (1/2)

[藤野圭一,NTT OSSセンタ]

TomcatのDBコネクション・プールは2つある

 @IT読者の皆さんは「Tomcat JDBC Connection Pool」をご存じですか? 通常、TomcatのDBコネクション・プールといえばApache Commonsプロジェクトの「Commons DBCP」を想像するかと思います。しかし、Tomcatには「Commons DBCP」以外にもDBコネクション・プールの実装が存在します。それが、「Tomcat JDBC Connection Pool」(以下、Tomcat JDBC Pool)です。

 Tomcat JDBC Poolとは、Apache Tomcatプロジェクトが独自に作成したDBコネクション・プールの実装のことです。

 実は、このTomcat JDBC Poolは数年前から開発されていて、Tomcat 7.0.18以前ではソースファイルから「extra」パッケージとして別途ビルドすることで利用可能でした。そして、Tomcat 7.0.19から正式にTomcatのバイナリパッケージに含まれることになりました。

 つまりTomcat 7では、標準で2つのDBコネクション・プールの実装が利用可能で利用者はどちらか好きな実装を選べます。

 本稿では、Tomcat 7.0.19から正式に採用されたTomcat JDBC Poolについて、Commons DBCPとの違いをベースに説明します。

Tomcat JDBC Poolのコンフィグレーション

 まずはコンフィグレーションについて説明します。Tomcat JDBC Poolでは、いくつか例外はありますが、基本的にCommons DBCPと同様の設定で利用可能です。

 パラメータの種類別にカテゴライズしてみました。順に説明します。

共通設定パラメータ

 まずはJDBC Driverに関するパラメータやトランザクションやコミットモードなどの基本パラメータについてです。以下の表にまとめました。

パラメータ名 説明
username コネクションを確立するためにJDBCドライバに渡される接続ユーザー名
password コネクションを確立するためにJDBCドライバに渡される接続パスワード
url コネクションを確立するためにJDBCドライバに渡される接続URL
driverClassName JDBCドライバのFQCN(Fully Qualified Class Name、完全修飾クラス名)
connectionProperties コネクションを確立するためにJDBCドライバに渡される接続プロパティ
defaultAutoCommit このプールで作成されたコネクションの自動コミットモード。未設定の場合はJDBC Driverのデフォルトが利用される
defaultReadOnly このプールで作成されたコネクションのReadOnlyの状態。未設定の場合はJDBC Driverのデフォルトが利用される
defaultTransactionIsolation このプールで作成されたコネクションのTransactionIsolation。未設定の場合はJDBC Driverのデフォルトが利用される
defaultCatalog このプールで作成されたコネクションのデフォルトカタログ。未設定の場合はJDBC Driverのデフォルトが利用される

 基本的にはDBCPとTomcat JDBC Pool間で同様に利用できます。ただし、defaultAutoCommitについてはデフォルトの意味がDBCPと異なります。defaultAutoCommitが未設定の場合、DBCPはtrueが設定されますが、Tomcat JDBC PoolはJDBC Driverのデフォルトが利用されます。つまり未設定の場合、setAutoCommitメソッドは呼び出されません、

 もう一点、JDBCドライバの配置場所についてDBCPとTomcat JDBC Pool では違いがあります。

 DBCP(1.3や1.4以降)の場合はTomcat共通の「lib」ディレクトリでも、Webアプリケーションの「WEB-INF/lib」でも、どちらにJDBCドライバを配置しても構いませんが、Tomcat JDBC Poolの場合は「tomcat-jdbc.jar」をロードするクラスローダが読めるディレクトに配置しないといけません。デフォルトの場合は、Tomcat共通のlibディレクトリになります。

コネクションプールに関するパラメータ

 次は、コネクションプールの初期サイズや最大コネクション数などのコネクションプールに関するパラメータです。

パラメータ名 説明 デフォルト値
initialSize プールの起動時に作成されるコネクションの初期サイズ 10
maxActive 同時にプールから割り当てることのできるアクティブなコネクションの最大数 100
maxIdle プールに保持しておく最大のコネクション数 maxActive
minIdle プールに保持する最小のコネクション数 initialSize
maxWait 利用可能なコネクションが存在しないときに待機する最大時間(ミリ秒単位) 30000
(30秒)
maxAge コネクションを保持する時間(ミリ秒単位)コネクション返却時に接続時間からmaxAge以上経過していたら、そのコネクションをクローズ。maxAgeによるチェックを行わない 0
fairQueue getConnectionの呼び出しが FIFO方式で公平に扱われることを希望する場合はtrueに設定。trueに設定することで、アイドル状態のコネクションリストに、org.apache.tomcat.jdbc.pool.FairBlockingQueue実装が使用され、スレッドが到着した順番でコネクションを獲得することが保証される true

 initialSize、maxActive、maxIdle、minIdle、maxWaitについてはデフォルト値に違いはありますが、DBCP と Tomcat JDBC Pool の間で同様に利用できます。

 なお、上記表にも記載していますが、「maxAge」によるコネクションの生存期間チェックと「fairQueue」によるアイドルコネクションリストの実装の切り替えが新機能として新たに追加されています。

バリデーションに関するパラメータ

 次は、バリデーションに関するパラメータです。DBサーバへ指定したタイミングでSQLクエリを発行し、コネクションの有効性を確認できます。

パラメータ名 説明 デフォルト値
validationQuery コネクションが有効か確認する際に発行するSQLクエリ文字列  
testOnBorrow プールからコネクションが貸し出される前にコネクションの有効性を検証。検証に失敗した場合は該当コネクションを破棄し、新たにプールからの取得を試みる。本機能を利用するにはtrueに設定し、validationQueryを設定する必要がある false
testOnReturn プールにコネクションを返却する前にコネクションの有効性を検証。本機能を利用するにはtrueに設定し、validationQueryを設定する必要がある false
testWhileIdle アイドル状態のコネクションの有効性を検証。検証に失敗した場合は該当コネクションを破棄。本機能を利用するにはtrueに設定し、validationQueryを設定する必要がある。さらに本機能はEvictorを利用するため、Evictorも有効にする必要がある(Evictionの項参照) false
initSQL コネクション作成時に実行されるクエリ文字列 未設定
validatorClassName バリデータクラス名を指定。本パラメータを設定するとvalidationQueryによるコネクションの有効性検証の変わりに、validatorクラスによるコネクションの有効性検証が行われる。validatorはorg.apache.tomcat.jdbc.pool.Validatorインターフェイスを実装する必要がある 未設定
validationInterval バリデーションの実行間隔を指定。前回の検証からこのパラメータ値以上経過していない場合は、コネクションの検証を行わない 30000
(30秒)

 コネクションのバリデーションについては、DBCP と同様に Tomcat JDBC Pool でも利用可能です。Tomcat JDBC Poolの場合は、従来のtestOnBorrow、testOnReturn、testWhileIdleでのタイミングに加えて、initSQLによるコネクション作成時のバリデーションも行えるようになりました。

 さらに、validationIntervalによるバリデーション間隔の調整によって、過剰なコネクションのバリデーションを抑制できます。

 また、validatorClassNameの指定によりコネクションの検証処理をJavaクラスとしてプログラミングできるようになり、validationQueryの実行だけではできないような複雑なコネクションの検証ができます。

 Validatorを作成するには、「org.apache.tomcat.jdbc.pool.Validatorをimplements」して、「validate(Connection con, int validateAction)」メソッドを実装するだけです。validateメソッドにオリジナルのコネクションチェック処理を記述してください。


public class TestValidator implements Validator {
 
    @Override
    public boolean validate(Connection con, int validateAction) {
        // validate connection
        return result;
    }
 
}

PreparedStatementのキャッシュに関するパラメータ

 DBCPで設定可能であったPreparedStatementのキャッシュに関する以下のパラメータは、Tomcat JDBC Poolでは利用できません。PreparedStatementのキャッシュをTomcat JDBC Poolで利用するには、後述するJdbcInterceptorを使用します。

パラメータ名 説明
poolPreparedStatements Tomcat JDBC Poolでは利用不可
maxOpenPreparedStatements Tomcat JDBC Poolでは利用不可

アイドル状態のコネクションに関するパラメータ「Eviction」

 アイドル状態のコネクションに関するパラメータは以下の通りです。

パラメータ名 説明
timeBetweenEvictionRunsMillis アイドル状態のコネクションをチェックする間隔。デフォルト5000(5秒)
numTestsPerEvictionRun Tomcat JDBC Poolでは利用不可
minEvictableIdleTimeMillis アイドルコネクションの生存期間

 変更点は、numTestsPerEvictionRunが利用不可になったことだけです。timeBetweenEvictionRunsMillisとminEvictableIdleTimeMillisは従来と同様に利用できます。

コネクションのクローズ漏れ検知のパラメータ「removeAbandoned」

 次は、コネクションのクローズ漏れ検知の設定です。プールから貸し出されたコネクションが長時間の間、クローズされなかった場合に、クローズ漏れとして検知して、ログ出力後(有効なら)、コネクションをクローズします。

パラメータ名 説明 デフォルト値
removeAbandoned クローズ漏れコネクションの検知を行う場合はtrueに設定 false
removeAbandonedTimeout クローズ漏れとみなすまでの時間 60秒
logAbandoned クローズ漏れを検知した際に、コネクションをクローズしていないアプリのスタックトレースをログに出力する場合に設定。ただし、コネクションの取得時にスタックトレースを生成する必要があるため、本機能利用時はオーバーヘッドが追加される false(無効)
suspectTimeout コネクションのクローズ漏れの容疑を掛けられるまでの時間suspectTimeoutを経過したクローズ漏れの疑いがあるコネクションに対して、警告ログ(logAbandoned有効時)とJMX通知を行う。ログ出力とJMX通知は1回のみ行われる 0(無効)
abandonWhenPercentageFull クローズ漏れコネクションを破棄する割合を設定します。 0から100の間で設定。この設定値を超えた場合にのみクローズ漏れのコネクションを破棄。removeAbandonedTimeoutを超えたコネクションは全て破棄 0

 Tomcat JDBC Pool では従来のremoveAbandoned機能に加えて、suspectTimeoutとabandonWhenPercentageFullが新規で追加されています。

その他

 最後に、どのカテゴリにも属さない、その他のパラメータです。

パラメータ名 説明 デフォルト値
accessToUnderlying
ConnectionAllowed
Tomcat JDBC Poolでは利用不可。実コネクションを取得する際は、Connectionのunwrap メソッドを呼び出すか、プールから取得したコネクションをjavax.sql.PooledConnectionでキャストしてからgetConnection()を呼び出す  
object_name コネクションプール名  
dataSource コネクションを取得するDataSourceを指定。DataSourceから取得する場合はjava.sql.DriverやURLなどは無視される 未設定
dataSourceJNDI dataSourceのJNDIを指定 未設定
jdbcInterceptors インターセプタの一覧をセミコロンで定義。これらのインターセプタは、コネクションに対する操作のチェーンへのインターセプタとして挿入される  
jmxEnabled コネクションプールをConnectionPoolMBeanとして登録 true
useEquals ProxyConnectionでString.equalsを使用してメソッド名を比較する場合はtrueを設定==使用したい場合はfalseを設定。この値はjdbcInterceptorに適用されないので、jdbcInterceptorごとに設定する必要がある true
useLock コネクションを利用する時にロックを取るかどうかを指定。PoolSweeperが有効な場合は常にtrueになる false
alternateUsername
Allowed
デフォルトでTomcat JDBC PoolはDataSource.getConnection(username,password) の呼び出しを無視し、DataSource.getConnection()を呼び出す。DataSource.getConnection(username,password) の呼び出しを有効にするにはtrueに設定する  

 accessToUnderlyingConnectionAllowed以外は全て新規パラメータです。

 dataSourceやdataSourceJNDIなどのコネクション取得先をデータソースから取得できるようにした拡張や、useEqualsやuseLockの内部実装の細かい追加までさまざまな種類があります。中でも「jdbcInterceptor」「jmxEnabled」は大きな拡張の1つなので、次ページで詳しく説明します。

       1|2 次のページへ

Copyright© 2017 ITmedia, Inc. All Rights Reserved.

@IT Special

- PR -

TechTargetジャパン

この記事に関連するホワイトペーパー

RSSについて

アイティメディアIDについて

メールマガジン登録

@ITのメールマガジンは、 もちろん、すべて無料です。ぜひメールマガジンをご購読ください。