メソッドキャンセルとは,タイムアウトの原因となっている実行中の処理をキャンセルする処理です。メソッドキャンセル時には,現在実行されている処理がキャンセルできるかどうかを判断します。
メソッドをキャンセルできる領域のことを非保護区,メソッドをキャンセルできない領域を保護区といいます。
保護区とは,メソッドキャンセルのできない領域です。保護区では,J2EEサーバの動作で共有されるデータや領域を保持したり,JavaVM内で行われる処理を保証したりするため,メソッドキャンセルができません。J2EEサービス,Webコンテナ,EJBコンテナが保護区に該当します。保護区として定義されている内容については,「付録C 保護区リストの内容」を参照してください。ここに記載されている保護区に該当するクラス以外で,保護区として扱いたいクラスがある場合は,保護区リストファイルに記述してください。
一方,非保護区は,メソッドキャンセルができる領域です。J2EEアプリケーションが非保護区になります。
保護区,非保護区の判定は,クラス単位で行われます。ただし,非保護区の場合は実行時の条件によって保護区として扱われることがあります。J2EEアプリケーションでも,ネイティブメソッドを呼び出している場合や,スタティックイニシャライザを実行している場合は,保護区と判定されます。また,Cosminexus Component Container 08-00から,java.lang.Objectクラスのwaitメソッドは,スタティックイニシャライザの延長での呼び出しではない場合だけ,例外的に非保護区と判定されます。※
注※ Cosminexus Component Container 08-00以降の場合,java.lang.Objectクラスのwaitメソッドは,指定時間の経過やnotify/notifyAllによって処理が再開される時に,スレッドのモニタ(ロック)を取得します。このモニタ取得待ちの間に保護区の判定を行った場合は,非保護区と判定されますが,実際にキャンセルが実行されるのはスレッドのモニタを取得した直後となります。
メソッドキャンセルは,現在実行中の処理が非保護区の場合だけ実行されます。メソッドキャンセルができるかどうかを確認するため,保護区の判定では,キャンセル対象となるメソッドが非保護区で実行中かどうかを判定します。実行している処理が非保護区の場合は,メソッドキャンセルが行われます。保護区の場合は,一定間隔で保護区の判定をリトライします。判定処理で保護区と判定されるたびに,KDJE52718-Wのメッセージが出力されます。一定時間内に非保護区に制御が移らない場合は,メソッドキャンセルが失敗したと見なされ,メソッドキャンセルの処理が終了します。
保護区の判定処理の流れを次の図に示します。
図5-2 保護区の判定処理の流れ
なお,メソッドキャンセル時にデータベースにアクセスしている場合,トランザクションは強制的にタイムアウトします。ステートメントキャンセル機能が有効な場合,トランザクションがタイムアウトすると,ステートメントキャンセル機能が有効な場合は実行中のSQLをキャンセルし,トランザクションはロールバックにマークされます。また,保護区を実行中のためにメソッドキャンセルが行われなくても,トランザクションは強制的にタイムアウトします。このとき,トランザクションはロールバックにマークされます。トランザクションタイムアウトの詳細については,マニュアル「Cosminexus アプリケーションサーバ 機能解説 基本・開発編(コンテナ共通機能)」の「3.15.8 トランザクションタイムアウトとステートメントキャンセル」を参照してください。
メソッドキャンセルを実行すると,キャンセル対象となるメソッドを実行中のスレッドで,ThreadDeathが発生します。WebコンテナおよびEJBコンテナでは,このThreadDeathをキャッチして必要な処理を実施します。
WebコンテナおよびEJBコンテナでのメソッドキャンセル時の動作について説明します。
ThreadDeathがスローされるタイミングによって動作が異なります。
EJBのメソッド呼び出し中にThreadDeathがスローされた場合は,EJB仕様で定められたシステム例外が発生した場合と同等の動作をします。呼び出し元に返る例外のgetCauseメソッドでは,ThreadDeathオブジェクトを返します。
メソッドキャンセル実行のタイミング,およびメソッドキャンセル実行までに掛かる最大の時間について説明します。
メソッドキャンセル処理は,コマンド実行後に非同期で実行されます。また,メソッドキャンセル処理は,メソッドキャンセル処理の時間間隔には影響されません。
メソッドキャンセル時,デフォルトではローカル変数情報がスタックトレースに出力されます。
性能への影響が出るおそれがあるため,メソッドキャンセル時にローカル変数情報をスタックトレースに出力しないように,JavaVM拡張オプションの「-XX:-HitachiLocalsInStackTrace」の設定を推奨します。