サーブレット、JavaServer Pages、またはエンタープライズ・セッシ ョン Bean のマイグレーション時の接続に関する考慮事項
WebSphere® Application Server バージョン 7.0 以降 にアップグレードする予定で、バージョン 1.2 の Java™ 2 Platform, Enterprise Edition (J2EE) 仕様から以降のバージョン (1.4 や Java Platform, Enterprise Edition (Java EE) など) にアプリケーションをマイグレーションする場合、バージョン 1.2 より後のバージョンのアプリケーション・コンポーネントでは、製品により、共有可能な接続と共有不可の接続が別々に割り振られるので注意してください。一部のアプリケーションでは、この違いにより、性能低下が生じることが あります。
悪影響を及ぼす振る舞い変更
WebSphere Application Server は J2EE 1.2 仕様にコーディングされたアプリケーション・モジュールとの 後方互換性を提供するため、WebSphere Application Server バージョン 7.0 以降 にマイグレーションした場合に、 バージョン 4 スタイル・データ・ソースを継続して使用することができます。 J2EE 1.2 モジュールにバージョン 4 データ・ソースのみを構成する限り、 ご使用のデータ・アクセス・アプリケーション・コンポーネントの振る舞いは変更されません。
ただし、WebSphere Application Server バージョン 7.0 以降 へのマイグレーションに伴い、 J2EE 仕様のより新しいバージョンを採用すると、ご使用のデータ・アクセス ・コンポーネントの振る舞いが変わる可能性があります。 具体的に、このリスクは、サーブレット、JavaServer Page (JSP) ファイ ル、または共有可能な接続を経由してローカル・トランザクション内で実行す るエンタープライズ・セッション Bean を含むアプ リケーションに起こる可能性があります。 データ・アクセス・コンポーネントの振る舞い変更は、このようなアプリケーションでの接続の使用に悪影響を及ぼす可能性があります。
この変更では、以下のメソッドを含むすべてのアプリケーションに影響が出ます。
- RequestDispatcher.include()
- RequestDispatcher.forward()
- JSP のインクルード ((<jsp:include>)
問題の症状には、以下のようなものがあります。
- セッションのハング
- セッション・タイムアウト
- 接続の不足
共有可能な接続と共有不可能な接続の割り振りの切り替え
バージョン 4 データ・ソースを使用する J2EE 1.2 モジュールでは、 WebSphere Application Server は JSP ファイル、サーブレット、およびエ ンタープライズ・セッション Bean に共有不可能な接続を実行します。 その他すべてのアプリケーション・コンポーネントには、共有可能接続を実行します。 ただし、J2EE 1.3 以降のモジュールでは、接続を個々のリソース参照で共有不可として指定しない限り、アプリケーション・サーバーは共有可能接続をすべての論理的に命名されたリソース (個々の参照にバインドされたリソース) に実行します。この状況において共有可能接続を使用すると、以下の影響があります。
- ユーザー・トランザクションの範囲外で受信および使用されたすべての接続が、 接続ハンドルで close() 呼び出しが発行されても、 カプセル化メソッドが戻るまでフリー接続プールに戻されない。
- ユーザー・トランザクションの範囲外で受信および使用されるすべての接続が、 他のコンポーネント・インスタンス (つまり、他のサーブレット、JSP ファ イル、またはエンタープライズ Bean) と共有されない。 例えば、セッション Bean 1 が接続を取得した後に、同じく接続を取得す るセッション Bean 2 を呼び出します。 すべてのプロパティーが同一であったとしても、それぞれのセッション Bean が独自の接続を受け取ります。
接続動作のこの変更をあらかじめ考慮しておかないと、アプ リケーション・コードが過度の接続を使用する構造を持ってしまう可能性があ ります。これは特に JSP インクルード、共有可能な接続を経由してローカル ・トランザクション内で実行するセッション Bean、 RequestDispatcher.include() ルーチン、 RequestDispatcher.forward() ルーチン、あるいはこれらのメソ ッドから他のコンポーネントへの呼び出しなどにおいて起きやすい問題です。 結果的に、セッション停止、セッション・タイムアウト、または接続 障害が生じることがあります。
シナリオの例
サーブレット A は接続を取得して作業を完了すると、接続をコミットした後、 その接続で close() を呼び出します。 次に、サーブレット A は RequestDispatcher.include() を呼び出してサーブレット B をインクルードします。サーブレット B は、サーブレット A と同じステップを実行します。サーブレット A の接続は現行メソッドから戻るまで空きプールに戻らないため、現時点では 2 つの接続がビジーになっています。このように、アプリケーションではユーザーが意図していたよりも多くの接続が使用されている可能性があります。 接続プールの「最大接続数」設定にこれらの接続の数が算入されていない場合、 この振る舞いによってプール内の接続数が不足し、ConnectionWaitTimeOut 例外が戻されます。 接続待ちタイムアウトが使用可能にされていないか、 接続待ちタイムアウトに大きな数値が設定されている場合、 これらのスレッドはプールに戻されることのない接続を待機していることになり、 ハングしているように見えることがあります。 新規の接続を待機しているスレッドは、新規の接続が利用できない場合、 現在使用している接続を戻しません。
解決方法
以下の方法で、これらの問題を解決します。
- 非共有接続を使用する。
ユーザー・トランザクションの範囲外で非共有接続を使用している場合、 その接続は close() 呼び出しが発行されたときにフリー・プールに戻されます (接続がコミットまたはロールバック されたと見なされます)。
- 最大接続数を増やす。
必要な接続の数を計算するには、構成されたスレッド数に (接続を使用する呼び出しの) コンポーネント呼び出しのネストの最深レベルを乗算します。 呼び出しのネストの説明については、シナリオの例のセクションを参照してください。