排他制御によってデータベースに一時的にアクセスできなかった場合など、エラーが発生しても同じ処理を再度実行することによって正常に処理が完了できる場合があります。このような場合に以下の機能を使用すると、自動的に同じ処理を再度実行することができます。
ビジネスクラスが例外を発生した場合に、ビジネスクラスを再度実行する機能です。
EJBセションBean (以降、単にセションBeanと呼びます) がアプリケーション例外を発生した場合に、再度自動的にセションBeanを呼び出す機能です。Apcoordinatorで作成したセションBeanを呼び出す場合に使用できます。
セションBeanの処理を再試行したい場合は、上記のどちらの機能を使用しても再試行が実現できます。この場合、上記2つの機能には以下の違いがあります。
使用する機能 | 左記機能を使用するアプリケーションと再試行の動作 | 利点 | 注意点 |
---|---|---|---|
ビジネスクラス再試行機能 | セションBeanで使用します。セションBeanの内部でビジネスクラスの処理を再試行します。 | 再試行時に呼び出し元との通信が発生しません。 | EJBコンテナがEJBの実行時間を監視してタイムアウト時にEJBを停止するよう設定している場合は、再試行中にタイムアウトとならないようにタイムアウト時間の設定に注意が必要です。 |
EJB再試行機能 | セションBeanの呼び出し側で使用します。呼び出し側でセションBeanの呼び出しを再試行します。 | 呼び出すセションBeanの内部で再試行を実装していない場合でも、再試行を実現できます。 | 再試行するたびにセションBeanとの通信が発生します。 |
以降では、ビジネスクラス再試行機能とEJB再試行機能の基本的な使用方法を説明します。これらの機能の詳細は以下を参照してください。
ビジネスクラス再試行機能
ビジネスクラス再試行機能を使用すると、以下の条件でビジネスクラスが再試行されます。
ビジネスクラスのうちコマンドマップで指定されたもの(以降、ビジネスメソッドと呼びます)が、例外としてjava.lang.Exceptionまたはそのサブクラスを発生した場合。ただしjava.lang.RuntimeExceptionとそのサブクラスは除きます。以降、再試行を起こす例外を再試行例外と呼びます。
com.fujitsu.uji.DispatchContextクラスのsetRetryメソッドが呼び出された場合。この場合、メソッドが再試行例外を発生しなくても、メソッドの終了後に再試行されます。例外を発生させずに再試行させたい場合にこのメソッドを使用します。
ビジネスクラス再試行機能を使用するには、com.fujitsu.uji.GenericRetriableHandlerクラスを継承してビジネスクラスを作成します。デフォルトでは再試行に関する設定は以下のとおりです。
再試行間隔は100ミリ秒です。ビジネスメソッドが再試行例外を発生した場合に、100ミリ秒待ってから再試行します。
再試行最大回数は2回です。2回再試行しても再試行例外が発生する場合はそれ以上再試行せずに例外を発生します。初回の実行を合わせて最大で合計3回ビジネスメソッドが実行されます。
GenericRetriableHandlerを継承したビジネスクラスのビジネスメソッド全てで再試行が有効です。
ビジネスクラス設定ファイルを作成すると、再試行の有無、再試行間隔、再試行最大回数をビジネスメソッドごとに指定できます。詳細については“4.6 ビジネスクラスの再試行”を参照してください。
EJB再試行機能
EJB再試行機能を使用すると、セションBeanがある特定のアプリケーション例外を発生した場合に、セションBeanの呼び出しが再試行されます。再試行を起こすアプリケーション例外を再試行例外と呼びます。再試行例外として使用する例外クラスはアプリケーション開発者が指定します。
EJB再試行機能を使用してEJBを呼び出すには、リモート共通インターフェイスを使用し、EJBを呼び出すアプリケーションを以下のように作成します。
リモートマップを作成して、呼び出すセションBeanの名前と再試行のパラメータを定義します。リモートマップは、リモート共通インターフェイスにおいて、呼び出されるアプリケーションを定義するXMLファイルです。 以下は、EJB再試行機能を使う場合のリモートマップの記述例です。
<?xml version="1.0" encoding="Shift_JIS"?> <remoteMap xmlns=http://interstage.fujitsu.com/schemas/uji/remoteMap xmlns:xsi=http://www.w3.org/2001/XMLSchema-instance xsi:schemaLocation="http://interstage.fujitsu.com/schemas/uji/remoteMap http://interstage.fujitsu.com/schemas/uji/remotemap.xsd"> <config> <version>5.0</version> </config> <!-- EJB再試行機能を使って呼び出すセションBeanを定義します。--> <ejbExt name="MySessionBean">
<application name="java:comp/env/ejb/MySessionBean" />
<retriableException class="some.pkg.BusyException" />
<retriableException class="some.pkg.NotReadyException" />
</ejbExt> </remoteMap>
ejbExtタグを使って呼び出すセションBeanを記述します。セションBeanに与える名前をejbExtタグのnameアトリビュートに指定します。ejbExtタグのコンテントには以下のタグを記述します。
JNDIで検索するセションBeanの名前をnameアトリビュートに指定します。
再試行例外を定義します。classアトリビュートに例外クラスを指定します。セションBeanを呼び出した結果、アプリケーション例外が発生し、その例外のクラスがclassアトリビュートに指定したクラスと同じか、そのサブクラスであった場合に、再試行します。なお、以下のクラスを再試行例外に指定することはできません。
java.lang.RuntimeExceptionとそのサブクラス
java.rmi.RemoteExceptionとそのサブクラス
java.lang.Exception
java.lang.Errorとそのサブクラス
また、必要に応じてejbExtタグには以下のアトリビュートを指定できます。
再試行最大回数を指定します。例えば2を指定すると、初回の呼び出しを含めて最大で合計3回呼び出されます。デフォルトは2です。
再試行例外を検出してから再試行するまでの時間をミリ秒単位で指定します。デフォルトは100ミリ秒です。
リモートマップは設定ファイルフォルダに置きます。設定ファイルフォルダは、コマンドマップ、リモートマップなどのApcoordinatorの定義ファイルを置くフォルダです。例えば、Webアプリケーションの場合は、WEB-INFディレクトリーです。
CallFactoryインターフェイスとCallインターフェイスを使ってセションBeanを呼び出します。
com.fujitsu.uji.ext.CallFactoryとcom.fujitsu.uji.ext.Callの2つのインターフェイスを使用してセションBeanを呼び出します。これらのインターフェイスは、リモート共通インターフェイスにおいてアプリケーションを呼び出すためのインターフェイスです。
CallFactoryインターフェイスとCallインターフェイスを使った呼び出しの手順は以下のとおりです。
com.fujitsu.uji.DispatchContextクラスからCallFactoryインターフェイスを取得します。
セションBeanの名前(ejbExtタグのnameアトリビュートに指定したもの)を指定してCallFactoryインターフェイスからCallインターフェイスを取得します。この処理によって、セションBeanオブジェクトが作成されます。
データBeanとコマンド名を引数としてCallインターフェイスのinvokeメソッドを呼び出すと、セションBeanが呼び出されます。セションBeanが再試行例外を発生した場合は、セションBeanが再度呼び出されます。
以下はビジネスクラスからセションBeanを呼び出す例です。
import com.fujitsu.uji.DispatchContext; import com.fujitsu.uji.ext.CallFactory; import com.fujitsu.uji.ext.Call; import com.fujitsu.uji.ext.UjiCreateException; import com.fujitsu.uji.ext.UjiRemoteException; import com.fujitsu.uji.ext.UjiTargetException; ... public Object doSomething(DispatchContext context, SomeBean dataBean) { // CallFactoryインターフェイスを取得します。
CallFactory factory = context.getCallFactory(); try { // セションBeanの名前を指定してCallインターフェイスを取得します。
Call call = factory.createCall("MySessionBean");
// 送信するデータとコマンド名を指定してセションBeanを呼び出します。
ResBean response = (ResBean)call.invoke(dataBean,"update"); } catch (UjiCreateException e) { ... } catch (UjiRemoteException e) { ... } catch (UjiTargetException e) { ... } ... }
再試行最大回数だけ再試行を繰り返してもセションBeanが例外を発生する場合、 invokeメソッドはcom.fujitsu.uji.ejb.EJBApplicationExceptionを発生します。セションBeanで発生した例外は、EJBApplicationExceptionのgetRootCauseメソッドにより取得できます。
再試行間隔、再試行最大回数の決定
再試行間隔、再試行最大回数は、アプリケーションに要求される応答時間を考慮して決定します。ビジネスクラスの実行時間(ビジネスクラス再試行機能の場合)や Callインターフェイスのinvokeメソッドの実行時間(EJB再試行機能の場合)の最大値は、以下の式で見積もれます。
処理時間 * (再試行最大回数 + 1) + 再試行間隔 * 再試行最大回数
ここで、処理時間は以下を指します。
ビジネスクラス再試行機能の場合、ビジネスメソッドとbeforeMethodCompletionメソッドの処理時間です。
EJB再試行機能の場合、EJB再試行機能を使用しない場合のinvokeの実行時間であり、EJBコンテナとの通信、EJBコンテナ上におけるセションBeanの実行時間を含みます。
注意
再試行間隔の精度はご使用になるシステムに依存します。 10ミリ秒より高い精度による指定はシステムによっては有効にならない場合があります。
関連項目
リモート共通インターフェイス
リモートマップ