Commons DBCP は、データベースのコネクション・プーリングを扱うライブラリです。
Tomcat で標準採用されています。
動作を簡単に説明します。
1. DBCPは、プール内に空き接続があるか確認
2. あればそれを返す。この時その接続は アクティブ となる
3. プール内に空き接続が無ければ、新たに接続を作って返す
1. 切断要求のあった接続をプール内に保管する。この時その接続は アイドル となる
2. もしプール内に maxIdle 以上の接続が溜まったら、それ以上にならないように接続を削除する
DBCPには接続監視スレッドというものが存在します。
これは一定時間毎にプール内のアイドル接続をチェックするものです。
デフォルトではこのスレッドは起動しません。
timeBetweenEvictionRunsMillis を1以上の値に指定すれば、その時間(ミリ秒)毎に処理が走ります。
設定ファイルの各種パラメータを解析します。対象バージョンは1.2.2です。
接続ユーザ名
接続パスワード
接続URL(JDBC)
使用するJDBCドライバクラスの完全限定名
その他接続に必要なプロパティを記述します。
プロパティ名(1)=プロパティ値(1);プロパティ名(2)=プロパティ値(2);
オートコミットモードの初期値を指定します。
デフォルト値は true です。これはJDBC接続のデフォルトでもあります。
リードオンリーモードの初期値を指定します。
デフォルト値はドライバに依存します。
いくつかのドライバでは、この値をサポートしていません。
TransactionIsolationレベルの初期値を指定します。
デフォルト値はドライバに依存します。
TRANSACTION_NONE, READ_COMMITTED, READ_UNCOMMITTED, REPEATABLE_READ, SERIALIZABLE
デフォルトのカタログ名を指定します。
プール開始時に確保する初期接続数を指定します。
デフォルト値は0です。
この値を1以上にすると、プール開始時(Tomcatならば最初のアプリケーションAccess時)に
この数だけの接続を実際にDBから確保します。
プール内のアイドル接続および現在使用中のアクティブ接続、
この合計数の最大値を指定します。
デフォルト値は8です。0以下の値を指定すると制限無しとなります。
この値は 実際にDBに要求する最大接続数 です。
プール内に存在可能なアイドル接続数の最大数を指定します。
接続切断時、DBCPはこの接続をプール内に溜めようとしますが
その時プール内にこの数以上の接続が存在した場合、接続は溜められず削除されます。
デフォルト値は8です。
負の値を指定すると制限無しとなります。
この場合、切断した接続は常にプール内に溜まります。
つまり、一度要求した接続は常にアクティブまたはアイドルの状態にあり、減ることはありません。
接続要求があったときに利用できる接続が存在しない(つまり接続数がmaxActiveに達している)場合に、
利用できるようになるまで待つ時間をミリ秒単位で指定します。
デフォルト値は-1です。この場合、永久に待ち続けます。
接続が有効であることを確認するためのSQL文を記述します。
このクエリは最低でも1行以上の行を返すSELECT文である必要があります。
MySQLでの例
SELECT 1
プールから取得する前に、接続の有効性を確認します。
ここで有効性が確認できない場合、SQLException がthrow されます。
この場合、例外をハンドリングする処理を開発者側で記述しなければなりません。
デフォルト値は true です。
validationQuery が指定されていない場合この値は false で上書きされます。
使用済接続をプールに返却する前に、接続の有効性を確認します。
ここで有効性が確認できない場合、接続はプールに保管されず破棄されます(例外は発生しない)。
ですが、普通このような状況はまずありません。
validationQuery に特殊なSQL文を記述して接続の有効性を
独自ロジックで判断したい場合などに使うのでしょう。
デフォルト値は false です。
validationQuery が指定されていない場合この値は false で上書きされます。
プール内のアイドル接続を一定時間毎に監視するスレッドを開始させます。
ここでは、監視処理を実施する間隔をミリ秒単位で指定します。
監視処理では以下の処理が実行されます。
デフォルト値は-1です。この値が0以下の場合、監視スレッドは起動されません。
監視処理時、アイドル接続数が最低でもこの数になるようにプール内に接続が生成されます。
これによって、常にプール内には一定数以上の接続が確保されることになります。
デフォルト値は0です。
この値は timeBetweenEvictionRunsMillis が1以上の場合のみ有効です。
監視処理時、アイドル接続の有効性を確認します。
もしここで有効性が確認できない場合、その接続はプールから削除されます。
デフォルト値は false です。
この値は timeBetweenEvictionRunsMillis が1以上の場合のみ有効です。
validationQuery が指定されていない場合、この値は false で上書きされます。
この値を true にすると、timeBetweenEvictionRunsMillis の時間毎に
最大 numTestsPerEvictionRun 件のSQL文が発行されます。
監視処理時、アイドル接続の生存期間をチェックします。
アイドル接続が一定の期間使われなかった場合、その接続をプールから削除します。
デフォルトでは 1000*60*30 、つまり30分です。
この値は、timeBetweenEvictionRunsMillis が1以上の場合のみ有効です。
例えば MySQL では8時間接続が使われないとその接続は無効になります。 監視処理スレッドを使えば、一定時間以上使われなかった接続は 自動的にプールから削除されるのでこれに対処できます。
1回の監視処理でチェックするアイドル接続数の最大値を指定します。
デフォルト値は3です。
この場合、例えばプール内に10個のアイドル接続が存在しても
1回の監視処理ではその中の3個だけしかチェックせず
残りは次の監視処理時にチェックすることになります。
また、この値を負数に設定すると「プール内接続数の何分の一をチェックする」という
割合による指定が可能になります。
例えばこの値を-3にすると、1回の監視処理で90個のアイドル接続中30個がチェックされます。
この値は、timeBetweenEvictionRunsMillis が1以上の場合のみ有効です。
Prepared Statementのプーリングを有効にします。
デフォルト値は false です。
プール内に保管する最大Prepared Statement数を指定します。
デフォルト値は0です。この場合、無制限に保管されます。
Underlying接続(詳細は不明)への接続を可能にします。
デフォルト値は false です。
一定時間アイドルの接続を削除するための設定項目ですが、現在は Deprecated となっています。
MySQLでは、接続しているセッションで何もせずに8時間が経過すると
自動的にその接続が切断される仕組みになっています。
この為、アイドルになった接続が8時間以上放置されると
その接続は無効になってしまいます。
この接続を使おうとすると、SQLExceptionが発生します。
これを回避するにはいくつかの方法がありますが
一番簡単かつ推奨されているのが監視スレッドを使う方法です。
timeBetweenEvictionRunsMillis に監視間隔を指定します。
こうすることによって、一定時間ごとに監視処理が走ることになります。
監視処理ではアイドル接続の生存期間をチェックして
一定時間(デフォルトで30分)使われなかった接続をプールから削除する処理を行います。
これによって、無効となった接続がプール内に残ってしまう事態を防げます。
Tomcat(5以降)での設定例
<Resource name="jdbc/XXX" auth="Container" type="javax.sql.DataSource" maxActive="100" maxIdle="30" maxWait="10000" username="XXX" password="XXX" driverClassName="com.mysql.jdbc.Driver" url="jdbc:mysql://HOST/DATABASE" timeBetweenEvictionRunsMillis="60000"/>
ちなみにMySQLでは接続を確保するのに1msも掛かりませんから、こうやって不要になった接続は
バンバン削除してしまってもパフォーマンスが低下することはほぼありません。