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メソッドにオリジナルのコネクションチェック処理を記述してください。
*** 一部省略されたコンテンツがあります。PC版でご覧ください。 ***
■ 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つなので、次ページで詳しく説明します。
Copyright © ITmedia, Inc. All Rights Reserved.