- PR -

Tomcatでコネクションプーリング時の情報取得

投稿者投稿内容
osiete
常連さん
会議室デビュー日: 2008/03/17
投稿数: 26
投稿日時: 2008-03-18 15:41
InitialContext initialContext = new InitialContext();
DataSource dataSource = (DataSource)initialContext.lookup(dataSourceName);
で接続しTomcatにコネクションプーリングをまかせています。

コネクション内のコネクション数などの情報を取得するにはどうすればいいのでしょうか?

よろしくお願いします。
いっきゅう
大ベテラン
会議室デビュー日: 2004/04/04
投稿数: 153
お住まい・勤務地: 兵庫
投稿日時: 2008-03-18 18:39
DataSourceをTomcatならおそらく
org.apache.commons.dbcp.BasicDataSource
にキャストすればgetNumActive()やgetNumIdle() で取得できるかと思います。
要は、DataSourceの実装次第です。
osiete
常連さん
会議室デビュー日: 2008/03/17
投稿数: 26
投稿日時: 2008-03-24 10:28
回答ありがとうございます。

別の質問になってしまうかもしれないですけど

System.out.println(dataSource.getClass());
eclipseでのデバックで確認した所
org.apache.tomcat.dbcp.dbcp.BasicDataSourceというクラスだったのですが
キャストするとClassCastExceptionになってしまいます。

また、
if(dataSource.getClass() == org.apache.tomcat.dbcp.dbcp.BasicDataSource.class){
if(dataSource instanceof org.apache.tomcat.dbcp.dbcp.BasicDataSource){
で確認するとfalseになってしまいます。


org.apache.tomcat.dbcp.dbcp.BasicDataSourceへのキャスト方法、
もしくは実装クラスをorg.apache.commons.dbcp.BasicDataSourceに
変更する方法ありましたらよろしくお願いします。

Tomcatのバージョンは5.5です。
koe
大ベテラン
会議室デビュー日: 2003/07/13
投稿数: 198
投稿日時: 2008-03-24 11:54
クラスローダが違うせいではないでしょうか。
getClass().getClassLoader()すると違いが分かると思います。

Tomcat5.5では、commons dbcpは
Commonクラスローダでロードされます。
実体は、5.5.25ではcommon/lib/naming-factory-dbcp.jarのようです。

Webアプリ側でも、WEB-INF/libにdbcpのjarをおかずに、
上記のjarファイルを使ってコンパイルして実行すれば、
上手く行くと思います。
osiete
常連さん
会議室デビュー日: 2008/03/17
投稿数: 26
投稿日時: 2008-03-24 14:35
回答ありがとうございます。

getClassLoaderをして確認してみた結果

dataSource.getClass().getClassLoader()は
org.apache.catalina.loader.StandardClassLoader@ff057f


org.apache.tomcat.dbcp.dbcp.BasicDataSource.class.getClassLoader()は
WebappClassLoader
delegate: false
repositories:
/WEB-INF/classes/
----------> Parent Classloader:
org.apache.catalina.loader.StandardClassLoader@132021a

と表示されました。
同一ではないということでしょうか???
クラスローダーのことがよく分からないのでこらから調べてみようと思います。

naming-factory-dbcp.jarはeclipseのプロジェクトのlibファイルにコピーして
パスを通していますこれだけだとだめなのでしょうか?

koe
大ベテラン
会議室デビュー日: 2003/07/13
投稿数: 198
投稿日時: 2008-03-24 16:01
Tomcatのクラスローダについては、こちらが参考になるでしょう。
http://tomcat.apache.org/tomcat-5.5-doc/class-loader-howto.html

引用:

osieteさんの書き込み (2008-03-24 14:35) より:
naming-factory-dbcp.jarはeclipseのプロジェクトのlibファイルにコピーして
パスを通していますこれだけだとだめなのでしょうか?



その場合、WebアプリケーションでBasicDataSourceクラスを参照すると、
WebappXクラスローダがクラスのロードを行います。
一方Tomcat側では、それより上位のCommonクラスローダがロードを
行いますので、クラスローダが異なり、エラーになるわけです。

対策としては、WEB-INF/libにコピーしたnaming-factory-dbcp.jarを
削除します。
代わりに、Eclipseから、Tomca付属のnaming-factory-dbcp.jarを
コピーせずに、「外部JARの追加」で直接参照して下さい。

これで、naming-factory-dbcp.jarを使ってコンパイルを通しつつ、
WebアプリケーションからもCommonクラスローダがロードした
クラスを参照できるようになります。
osiete
常連さん
会議室デビュー日: 2008/03/17
投稿数: 26
投稿日時: 2008-03-26 10:39
回答ありがとうございます。

外部パスで設定することにより無事にキャストして情報を取得することができました。
クラスパスのページは翻訳してみてみます。

別のスレッドで質問した方がいいかもしれませんが
2台のPCでwebサーバーにアクセスしそれぞれ1回づつgetConnectionを行う
と1台目ではgetNumActiveの結果が1で1台目のアクセスが終わる前に
2台目でgetConnectionを行うと結果が2にならないのでしょうか?

自分の環境では1台目、2台目ともにgetNumActiveの結果が1になってしまいます。
トランザクション制御をSpringの
org.springframework.transaction.interceptor.TransactionInterceptorクラスを
使用しているからなのでしょうか?
それともそういうものなのでしょうか?

理解不足ですみませんがよろしくお願いします。
いっきゅう
大ベテラン
会議室デビュー日: 2004/04/04
投稿数: 153
お住まい・勤務地: 兵庫
投稿日時: 2008-03-26 17:43

> 自分の環境では1台目、2台目ともにgetNumActiveの結果が1になってしまいます。
> トランザクション制御をSpringの
> org.springframework.transaction.interceptor.TransactionInterceptorクラスを
> 使用しているからなのでしょうか?

Springを使わずにベタで書けばそんなことはありませんでした。(2台目は2が戻ります)
考えられるのは、「synchronized」などで非同期になっていないか
Connectionをどこかで共有?しているかですが
Springフレームワークを使ったことが無いので回答とはいきませんが
コメント入れときます。

スキルアップ/キャリアアップ(JOB@IT)