[Seasar-user:9345] Re: コネクションプールの使われ方

Koichi Kobayashi [E-MAIL ADDRESS DELETED]
2007年 7月 22日 (日) 22:00:09 JST


小林 (koichik) です.

Date:    Sun, 22 Jul 2007 16:48:41 +0900
From:    "Umebayashi Tsuyoshi" <[E-MAIL ADDRESS DELETED]>
To:      <[E-MAIL ADDRESS DELETED]>
Subject: [Seasar-user:9344] コネクションプールの使われ方

> 上記セットで作成されたWEBアプリケーションを
> 解析しているのですが、いまいちよくわからないところがあります。
> 
> 1.画面へリクエストが発生
> 2.Serviceコンポーネントよびだされる
> 3.s2-daoを使用してDBへアクセスが行われる
> 4.レスポンスを返す
> 
> この際のコネクションプールの使われ方が
> どうもよくわかりません...

キーとなるのはトランザクションです.
Seasar2 では JTA (Java Transaction API) に準拠した
トランザクションマネージャを使用します.
スレッド上で JTA トランザクションが開始されると,
現在のスレッドにトランザクションが関連づけられます.
# TreadLocal で Transaction オブジェクトを管理します.

コネクションプールはこの JTA トランザクションと
密接に関係しています.

コネクションプールはコネクションが要求されると
現在のスレッドのトランザクションに関連づけられた
コネクションが存在するかチェックします.
もしなければ,プールされているコネクションから
フリーのコネクションを取り出します.
もしプールにフリーのコネクションがなければ,
新たにコネクションを作成します (これが「物理的な
コネクションを取得しました」というメッセージ).
そしてコネクションを現在のスレッドのトランザクションに
関連づけて呼び出し側 (S2Dao) に返します (これが
「論理的なコネクションを取得しました」).

S2Dao がコネクションをクローズしても,実際には
コネクションはクローズされず,現在のスレッドの
トランザクションに関連づけられたままとなります
(これが「論理的なコネクションを閉じました」).

同じスレッド上で (つまり同じトランザクション内で)
またコネクションが要求されると,今度は現在の
スレッドのトランザクションに関連づけられた
コネクションが存在するので,そのコネクションを
取り出します (これが「論理的なコネクションを
取得しました」).

現在のスレッドのトランザクションがコミットまたは
ロールバックされると,トランザクションに関連づけられた
コネクションは切り離され,フリーのプールに戻されます.
もしプールするコネクションの上限を超えていれば,
コネクションは本当にクローズされます (これが
「物理的なコネクションを閉じました」).

フリーのプールに保持されているコネクションは,
使用されないままタイムアウト期間を超えると
クローズされます (これも「物理的なコネクションを
閉じました」).

このため,通常 S2Dao を使用すると,次のように
ログが出力されます.

1.トランザクションを開始しました
2.物理的なコネクションを取得しました
3.論理的なコネクションを取得しました
4.論理的なコネクションを閉じました
5.(Dao の呼び出し毎に 3〜4 の繰り返し)
6.トランザクションをコミットしました
7.(10 分後に) 物理的なコネクションを閉じました

となります.

> 一つのServiceで1プールを占有して使用するのか
> s2-daoが呼ばれる度にプールの取得と開放が繰り返されるのか。

上記の説明の通り,コネクションは現在のスレッドの
トランザクションに関連づけられます (占有されます).
もし Service のメソッドがトランザクション境界に
なっているなら,実質的には Service のメソッドが
呼び出されている間はコネクションが占有されていると
考えてもほとんどの場合間違いではありません.

> 一つのServiceで2種類のdaoを使用していた場合は
> 2つのコネクションプールが使用されるのでしょうか?

それぞれの Dao が同じ DataSource を使用するなら,
同じトランザクション内で呼び出された場合には
同じコネクションプールから同じコネクションを
取得して使用することになります.

> またこの参考になるページがあれば
> 教えて頂けませんでしょうか。

JTA の仕様書とか.(^^;
いきなり読むのは大変だと思いますが,興味があれば是非.
JTA の仕様書は以下から入手できます.

http://java.sun.com/products/jta/

「Java Transaction API Specification 1.0.1B
Maintenance Release of Maintenance Reviews」
という記述の下の「Download」をクリックして,次ページで
「Accept」をチェックして jta-1_0_1B-spec.pdf を
ダウンロードしてください.
# JTA1.1 の仕様書はうまくダウンロードできないみたい.

その中の P26 から始まる
「4.2 Transaction Association and Connection Request Flow」
がお望みの情報 (の一部) です.

それに加えて JDBC 仕様書の「Connection Pooling」や
J2EE Connector Architecture 仕様書の「Connection Management」
を参照すると,標準的なコネクションプールの振る舞いが
理解できると思います.

JDBC 4.0 の仕様書は以下から取得できます.

http://jcp.org/aboutJava/communityprocess/final/jsr221/index.html

J2EE Connector Architecture 1.5 の仕様書は以下から
取得できます.

http://java.sun.com/j2ee/connector/download.html


仕様書を見るのが辛ければ,ソースを読む方がいいかも.
S2 の JTA  やコネクションプールはシンプルなので,
その方が簡単だと思います.
関連するのは s2-extension の以下のパッケージです.

org.seasar.extension.dbcp
org.seasar.extension.dbcp.impl
org.seasar.extension.jta
org.seasar.extension.jta.xa




-- 
<component name="koichik">
    <property name="fullName">"Koichi Kobayashi"</property>
    <property name="email">"[E-MAIL ADDRESS DELETED]"</property>
    <property name="blog">"http://d.hatena.ne.jp/koichik"</property>
</component>



Seasar-user メーリングリストの案内