Tomcat JDBC Poolを使うには
実際にTomcat JDBC Poolを使用してみましょう。設定は非常に簡単です。
■ Resourceの設定を少し変えるだけ
現在使用しているDataSourceを利用するResourceの設定に以下のようにfactory属性にorg.apache.tomcat.jdbc.pool.DataSourceFactoryを指定します。
*** 一部省略されたコンテンツがあります。PC版でご覧ください。 ***
以上で終了です。これで、DBCPの代わりにTomcat JDBC Poolが利用できます。
Resourceに設定されてあるその他のパラメータについては、前述の説明を参考に変更してください。基本的にそのままの設定でもマイグレーション可能です。アプリケーションには何の変更もありません。今まで通り利用できます。
■ 拡張されたJMXサポート
Tomcat JDBC PoolではCommons DBCPと比べてJMXサポートでいくつかの改良が加えられています。上記で説明した各属性以外にも、コネクション取得待ちのスレッド数を取得するwaitcount属性や、checkIdle、checkAbandoned、testIdleなどのプール内のコネクションに対するバリデーションを、以下のようにJMX経由で行えます。
- checkIdle:アイドル状態でminIdle以上のコネクションに対してのバリデーションを実行
- checkAbandoned:クローズ漏れコネクションの破棄を実行
- testIdle:全てのアイドルコネクションに対してバリデーションを実行
さらにjmxEnabledを有効にすることで、「tomcat.jdbc」ドメインでコネクションプールをMBeanとして登録できます。コネクションプールをJMXで登録することで、コネクションプールの属性やオペレーション以外にも、リスナによるJMX通知の受け取れます。
ちなみにTomcat JDBC Poolは標準で、コネクションプールの初期化失敗時や実コネクションの接続失敗時にそれぞれ通知します。
また、removeAbandonによるクローズ漏れコネクションに対する通知を、実際に破棄するときとsuspectTimeoutによる警告発生時の両方に通知します。
DBアクセスを拡張する「JdbcInterceptor」とは
JdbcInterceptorはTomcat JDBC Poolに追加された最も大きな機能の1つです。JdbcInterceptorはDBアクセスをインターセプトし、なんらかの処理を追加するために利用されます。JdbcInterceptorは自分で独自のものを作成できますし、Tomcatがデフォルトで用意しているものも利用できます。
まずはTomcatがデフォルトで用意しているJdbcInterceptorを5つ紹介します。
■ 【1】org.apache.tomcat.jdbc.pool.interceptor.ConnectionState
コネクション属性のautoCommit, readOnly, transactionIsolationをキャッシュするJdbcInterceptorです。
これらの属性のsetterやgetterが呼ばれたときにキャッシュを利用することでデータベースとの余分なやりとりを避けられます。
■ 【2】org.apache.tomcat.jdbc.pool.interceptor.StatementFinalizer
createStatement、prepareStatement、prepareCallを使用して作成されたすべてのステートメントを追跡して、コネクションがプールに返却される際にこれらのステートメントをcloseします。
■ 【3】org.apache.tomcat.jdbc.pool.interceptor.StatementCache
ステートメントをキャッシュするJdbcInterceptorです。
■ 【4】org.apache.tomcat.jdbc.pool.interceptor.SlowQueryReport
Slowクエリを報告するためのJdbcInterceptorです。Slowクエリの報告にJMX通知を利用したSlowQueryReportJmxも利用可能です。
■ 【5】org.apache.tomcat.jdbc.pool.interceptor.ResetAbandonedTimer
クローズ漏れコネクション検知までのタイマーをリセットするJdbcInterceptorです。removeAbandonedTimeoutを小さい値に設定しており、コネクションを多くの回数利用するバッチプログラムなどで利用されます。
JdbcInterceptorの使い方
次に、JdbcInterceptorの設定方法を紹介します。jdbcInterceptors属性にセミコロン区切りでJdbcInterceptorを指定してください。
通常はFQCNで指定しますが、単にクラス名だけの指定も可能です。その場合は「org.apache.tomcat.jdbc.pool.interceptor.」がパッケージが自動的に付与されます。また、「jdbcInterceptors="StatementFinalizer(useEquals=true)" 」のようにプロパティ値も同時に指定可能です。
最後に、JdbcInterceptorを作成方法を説明します。まずは簡単なサンプルをご覧ください。
*** 一部省略されたコンテンツがあります。PC版でご覧ください。 ***
「public class SampleInteceptor extends JdbcInterceptor {」でサンプルクラスは「org.apache.tomcat.jdbc.pool.JdbcInterceptor」クラスを継承します。
「public void reset(ConnectionPool pool, PooledConnection connection) {」では、抽象メソッドの「reset(ConnectionPool, PooledConnection)」を実装しています。resetメソッドはコネクションプールからコネクションを取得した際の初期化処理として呼び出されます。
また、コネクションクローズ時にも引数にnullが指定された状態で終了処理として呼び出されます。自作のJdbcInterceptorの初期化&終了処理を実装してください。
以上が、JdbcInterceptorの作成における最低限やらなくてはならないことです。
その他のJdbcInterceptorのメソッドは任意でオーバーライドします。では、どのようなメソッドがあるか紹介します。
■ 【1】public Object invoke(Object proxy, Method method, Object[] args)
invokeメソッドはコネクションに対する操作が呼び出されたときに実行されます。
特定の操作の前後に任意の処理を差し込めます。メソッド名の比較にはJdbcInterceptor#compareメソッドを使用します。
また、JdbcInterceptorはそれぞれチェーンでつながっているので、次のJdbcInterceptorに処理をつなげたい場合は、サンプルのように「super.invoke(proxy,method,args)」で次のJdbcInterceptorを呼び出す必要があります。処理を終了させたい場合は、「super.invoke(proxy,method,args)」を呼び出す必要はありません。
■ 【2】public void disconnected(ConnectionPool parent, PooledConnection con, boolean finalizing)
disconnectedメソッドは実コネクションが切断されたときに呼び出されます。
■ 【3】public void poolStarted(ConnectionPool pool)
poolStartedメソッドはコネクションプールの起動時に呼び出されます。
■ 【4】public void poolClosed(ConnectionPool pool)
poolClosedメソッドはコネクションプールのclose時に呼び出されます。
コネクションの非同期取得「getConnectionAsync」
最後に紹介するのはコネクションの非同期取得です。Tomcat JDBC Poolでは非同期でコネクションを取得できます。コードはこんな感じです。
*** 一部省略されたコンテンツがあります。PC版でご覧ください。 ***
コネクションが取得できるまで、別処理ができます。しかし、Tomcat JDBC Poolにものすごく依存してしまうので、使いどころが難しいですね。
高機能だが、採用実績はこれから
以上でTomcat JDBC Poolの説明は終わりです。Tomcat JDBC Poolは、いかがでしたでしょうか?
Commons DBCPからほとんど変更なくTomcat JDBC Poolに移行できま、さらに、JMXサポートの拡張による外部からコネクションプールのバリデーションや、JdbcInterceptorによるDB処理へ独自の処理を追加しカスタマイズできるなど、さまざまな改良が加えられています。
ソースコードもCommons DBCPと比べると非常にシンプルです。リリース間隔もTomcatと同時に行われるので、DBCPよりも大分速いでしょう。バグ修正されたものの、いつまでたっても修正版がリリースされないということはありません。
良いことばかりのように見えるTomcat JDBC Poolですが、利用実績でいうとCommons DBCPに到底およびません。これからいろいろなところで利用され、実績も増えていくのではないでしょうか。
Copyright © ITmedia, Inc. All Rights Reserved.
関連記事
- Strutsの常識を知り、EclipseとTomcatの環境構築
- Tomcatはどこまで“安全”にできるのか?
- 第6回 【真夏の夜のミステリー】Tomcatを殺したのは誰だ?(2007/8/27)
- 第7回 【トラブル大捜査線】失われたコネクションを追え!(2007/9/25)
- 第8回 肥え続けるTomcatと胃を痛めるトラブルハッカー (2007/11/27)
- 第14回 数百キロのコードでブルー - ドクターTomcat緊急救命 (2010/5/25)
- AWS ToolkitでTomcatクラスタをEC2上に楽々構築
- Java屋がTomcatでRuby on Railsを試すには?
- EclipseベースIDEとTomcatで始めるFlex+Java開発
- 狙われる甘〜いTomcat