DBコネクションのプーリングを改めてお勉強。
@IT:現場に活かすJakarta Project 第6回
んで、CommonsのDBCPのソースを眺めてみたり。
org.apache.commons.dbcp.PoolableConnectionクラスがコネクションのラッパクラスで、closeメソッドみたら返却ってなコードになってる。
で、いわゆるDBのコネクションのcloseとは違うみたいね。
org.apache.commons.dbcp.GenericObjectPool#borrowObjectが、プーリングからコネクションを貸し出すロジックの肝か。
Ping Queryってのは、org.apache.commons.dbcp.BasicDataSourceのvalidationQueryの値を指定すればいいのね。
validationQueryを指定していないと、activeかどうかテストしないよと。
DBCPでは、org.apache.commons.dbcp.PoolableConnectionFactory#validateConnectionでPing QueryのSQL投げて、borrowObjectで例外拾って、コネクションを破棄して、も一回プールからコネクションを取得しますよと。
// GenericObjectPool#borrowObjectの抜粋 // activate & validate the object try { // 取得したオブジェクトアクティブにする _factory.activateObject(pair.value); // validationQueryのSQLで確認 // (_testOnBorrowはvalidationQueryが設定されてたらtrue) if(_testOnBorrow && !_factory.validateObject(pair.value)) { throw new Exception("ValidateObject failed"); } return pair.value; } catch (Throwable e) { // SQLで確認して例外をキャッチしたら // object cannot be activated or is invalid try { // コネクションを破棄して _factory.destroyObject(pair.value); } catch (Throwable e2) { // cannot destroy broken object } synchronized (this) { _numActive--; notifyAll(); } if(newlyCreated) { throw new NoSuchElementException("Could not create a validated object, cause: " + e.getMessage()); } else { // 再度プールからコネクションを取得する continue; // keep looping } }
validationQueryを指定しとけば、DBMSでコネクションのタイムアウトが設定されたり、Webアプリと同期しないでサービスが再起動されるような場合でも、プーリングできます(コネクションを破棄して再取得します)よと。
Cosminexusの中のリソース参照のコネクションプーリングは、ちゃんとPing Queryでコネクションの生死を確認して、コネクションがDBMS側から切断されてる場合に、コネクションを破棄して再取得して、貸し出してると見える。