Hitachi

Cosminexus V11 アプリケーションサーバ 機能解説 運用/監視/連携編


5.3.4 メソッドキャンセルとは

メソッドキャンセルとは,タイムアウトの原因となっている実行中の処理をキャンセルする処理です。メソッドキャンセル時には,現在実行されている処理がキャンセルできるかどうかを判断します。

ポイント

Connector 1.5仕様に準拠したリソースアダプタを使用している場合,次の処理はメソッドキャンセルの対象にできません。

  • リソースアダプタ独自のメソッド

  • ワーク管理で実行されているWork

ただし,Workによって呼び出されたMessage-driven Bean内の処理については,メソッドキャンセルの対象にできます。

〈この項の構成〉

(1) 保護区と非保護区

メソッドをキャンセルできる領域のことを非保護区,メソッドをキャンセルできない領域を保護区といいます。

保護区とは,メソッドキャンセルのできない領域です。保護区では,J2EEサーバの動作で共有されるデータや領域を保持したり,JavaVM内で行われる処理を保証したりするため,メソッドキャンセルができません。J2EEサービス,Webコンテナ,EJBコンテナが保護区に該当します。保護区として定義されている内容については,「付録C 保護区リストの内容」を参照してください。ここに記載されている保護区に該当するクラス以外で,保護区として扱いたいクラスがある場合は,保護区リストファイルに記述してください。

一方,非保護区は,メソッドキャンセルができる領域です。J2EEアプリケーションが非保護区になります。

保護区,非保護区の判定は,クラス単位で行われます。ただし,非保護区の場合は実行時の条件によって保護区として扱われることがあります。J2EEアプリケーションでも,ネイティブメソッドを呼び出している場合や,スタティックイニシャライザを実行している場合は,保護区と判定されます。また,java.lang.Objectクラスのwaitメソッドは,スタティックイニシャライザの延長での呼び出しではない場合だけ,例外的に非保護区と判定されます。

注※ java.lang.Objectクラスのwaitメソッドは,指定時間の経過やnotify/notifyAllによって処理が再開される時に,スレッドのモニタ(ロック)を取得します。このモニタ取得待ちの間に保護区の判定を行った場合は,非保護区と判定されますが,実際にキャンセルが実行されるのはスレッドのモニタを取得した直後となります。

(2) メソッドキャンセルの処理

メソッドキャンセルは,現在実行中の処理が非保護区の場合だけ実行されます。メソッドキャンセルができるかどうかを確認するため,保護区の判定では,キャンセル対象となるメソッドが非保護区で実行中かどうかを判定します。実行している処理が非保護区の場合は,メソッドキャンセルが行われます。保護区の場合は,一定間隔で保護区の判定をリトライします。判定処理で保護区と判定されるたびに,KDJE52718-Wのメッセージが出力されます。一定時間内に非保護区に制御が移らない場合は,メソッドキャンセルが失敗したと見なされ,メソッドキャンセルの処理が終了します。

保護区の判定処理の流れを次の図に示します。

図5‒2 保護区の判定処理の流れ

[図データ]

なお,メソッドキャンセル時には,次の処理が実施されます。

上記の処理は,保護区を実行中のためにメソッドキャンセルが行われない場合も実施されます。

トランザクションタイムアウトの詳細については,マニュアル「アプリケーションサーバ 機能解説 基本・開発編(コンテナ共通機能)」の「3.15.8 トランザクションタイムアウトとステートメントキャンセル」を参照してください。

(3) WebコンテナおよびEJBコンテナでのメソッドキャンセル時の動作

メソッドキャンセルを実行すると,キャンセル対象となるメソッドを実行中のスレッドで,ThreadDeathが発生します。WebコンテナおよびEJBコンテナでは,このThreadDeathをキャッチして必要な処理を実施します。

WebコンテナおよびEJBコンテナでのメソッドキャンセル時の動作について説明します。

(a) Webコンテナでの動作

ThreadDeathがスローされるタイミングによって動作が異なります。

Webアプリケーションのフィルタ/サーブレット/JSPでのリクエスト処理中にThreadDeathがスローされた場合

呼び出し元となるフィルタ/サーブレット/JSPにjavax.servlet.ServletExceptionがスローされます。

例えば,フィルタからjavax.servlet.FilterChainのdoFilterメソッド呼び出しの延長でサーブレットが実行され,そのサーブレットの実行中にThreadDeathが発生した場合,doFilterメソッドの呼び出しで,javax.servlet.ServletExceptionがスローされます。

同様に,javax.servlet.RequestDispatcherのforwardメソッド,またはincludeメソッドを呼び出して,リクエストをサーブレット/JSPに転送した場合,javax.servlet.ServletExceptionのgetRootCauseメソッドでは,ThreadDeathオブジェクトを返します。

Webアプリケーションのリスナの処理中にThreadDeathがスローされた場合

WebコンテナはThreadDeathをキャッチしますが,リスナが呼び出される契機となったイベントの発生元となるユーザプログラム処理に対しては,例外はスローされません。

例えば,javax.servlet.http.HttpServletRequestのgetSessionメソッドの呼び出しによってHttpSessionを作成した場合,javax.servlet.http.HttpSessionListenerのsessionCreatedメソッドが呼び出されます。このsessionCreatedメソッドの実行中にThreadDeathがスローされた場合,WebコンテナはスローされたThreadDeathをキャッチしますが,HttpSession生成のイベントを発生させたgetSessionメソッド呼び出しには例外をスローしません。

(b) EJBコンテナでの動作

EJBのメソッド呼び出し中にThreadDeathがスローされた場合は,EJB仕様で定められたシステム例外が発生した場合と同等の動作をします。呼び出し元に返る例外のgetCauseメソッドでは,ThreadDeathオブジェクトを返します。

(4) メソッドキャンセル実行のタイミング

メソッドキャンセル実行のタイミング,およびメソッドキャンセル実行までに掛かる最大の時間について説明します。

メソッドキャンセル処理は,コマンド実行後に非同期で実行されます。また,メソッドキャンセル処理は,メソッドキャンセル処理の時間間隔には影響されません。

(5) メソッドキャンセル時の注意事項

メソッドキャンセル時,デフォルトではローカル変数情報がスタックトレースに出力されます。

性能への影響が出るおそれがあるため,メソッドキャンセル時にローカル変数情報をスタックトレースに出力しないように,JavaVM拡張オプションの「-XX:-HitachiLocalsInStackTrace」の設定を推奨します。