EJBタイマーサービスでは、以下のようなタイマーを作成し、任意の時刻にEJBコンテナからコールバック処理を実行させることができます。
一定時間経過後にコールバック
一定時間経過後にコールバック、その後定期的にコールバック
指定日時にコールバック
指定日時にコールバック、その後定期的にコールバック
以下について説明します。
基本機能
タイマーは、javax.ejb.TimerServiceインタフェースのcreateTimerメソッドを実行して生成します。createTimerメソッドの引数に実行時刻や実行間隔を指定します。EJBタイマーサービス(javax.ejb.TimerServiceインタフェースの実装)は、以下の方法で取得できます。
EJBコンテナより渡されるEJBコンテキストのgetTimerServiceメソッドを実行する。
javax.ejb.TimerService型のフィールドに@Resourceアノテーションを付与する。
生成したタイマーをキャンセルするには、生成したタイマーのcancelメソッドを実行します。
タイマー生成時に指定した時刻に、EJBタイマーサービスより各Enterprise Beanのタイマーコールバックメソッドを実行します。タイマーコールバックメソッドは、以下のいずれかで定義できます。
コールバックしたいメソッドに@Timeoutアノテーションを定義する。
Beanクラスがjavax.ejb.TimedObjectインタフェースを実装し、ejbTimeoutメソッドを定義する。
deployment descriptor(ejb-jar.xml)ファイルのtimeout-methodタグにタイマーコールバックメソッド名を定義する。
タイマーは、データベースに永続化します。Interstage Java EE 6 DASサービス起動時にタイマー情報をデータベースから取得するため、Interstage Java EE 6 DASサービスが再起動されると、タイマーが自動的に回復します。
タイマーの永続化について
タイマーを使用する場合、永続化のためのデータベースが必要です。使用するデータベースを用意してください。
タイマーをトランザクション内で生成すると、トランザクションの終了時にトランザクションのステータスに従って、タイマー情報の登録もコミットまたはロールバックされます。そのため、タイマーを使用するトランザクション内で別のJDBCデータソースやJMSリソースをアクセスする場合、グローバルトランザクションに対応するデータソース(XADataSource)を使用する必要があります。
グローバルトランザクションを使用すると性能のオーバーヘッドがあるため、タイマー生成処理やコールバック処理でJDBCのAPIまたはJPAを使用してデータベースにアクセスする場合には、タイマー永続化にも同じデータソースを使用することを推奨します。
以下の表にデータベースに用意するテーブルを示します。テーブル名は、「EJB__TIMER__TBL」にしてください。
カラム名 | データ型のJDBCタイプ | データの長さ(最大値) | 制約 |
---|---|---|---|
TIMERID | VARCHAR | 62 | PRIMARY KEY |
OWNERID | VARCHAR | 6 | NULL |
CREATIONTIMERAW | BIGINT | 19桁(9223372036854775807) | NOT NULL |
BLOB | LONGVARBINARY | プライマリキーと情報オブジェクトのバイナリサイズによる | NULL |
CONTAINERID | BIGINT | 19桁(9223372036854775807) | NOT NULL |
STATE | INTEGER | 1桁 | NOT NULL |
PKHASHCODE | INTEGER | 10桁(2147483647) | NOT NULL |
INTERVALDURATION | BIGINT | 19桁(9223372036854775807) | NOT NULL |
INITIALEXPIRATIONRAW | BIGINT | 19桁(9223372036854775807) | NOT NULL |
LASTEXPIRATIONRAW | BIGINT | 19桁(9223372036854775807) | NOT NULL |
SCHEDULE | VARCHAR | @Sucheduleアノテーション(注)に設定した引数による | NULL |
APPLICATIONID | BIGINT | 19桁(9223372036854775807) | NOT NULL |
注)@ScheduleアノテーションについてはEJB規約を参照してください。
JDBCタイプとDBMSのSQLデータ型のマッピングについては、JDBCドライバのマニュアルを参照してください。
タイマーサービスの永続化は、以下のデータベースをサポートします。
アプリケーション開発時やサンプル動作のためにJava DBデータベースも使用できますが、動作保証されません。
Symfoware
Oracle
SQL Server
EJBタイマーサービス用のデフォルトデータソースと接続プールを使用することで、タイマー用のテーブルを用意したJava DBデータベースを以下に作成することができます。Interstage Java EE 6 DASサービスを起動する前に、このデータベースをasadminコマンドのstart-databaseサブコマンドにより起動してください。
C:\Interstage\F3FMisje6\glassfish\databases
/opt/FJSVisje6/glassfish/databases
上記データベースを利用する場合、デフォルトデータソース「jdbc/__TimerPool」をInterstage Java EE 6 DASサービスのタイマーデータソースに指定してください。また、デフォルトの接続プールは「__TimerPool」です。EJBタイマーサービスで利用するデータベースを変更する場合は、__TimerPoolの設定を変更するか、デフォルトデータソース「jdbc/__TimerPool」に関連付けるJDBC接続プールを変更してください。JDBC接続プールの設定変更については「5.10 データベースの環境設定」を参照してください。
データベースごとのテーブル生成のDDLファイルが、以下に格納されています。DDLを参照しテーブルを生成してください。
C:\Interstage\F3FMisje6\glassfish\lib\install\databases
/opt/FJSVisje6/glassfish/lib/install/databases
データベース | DDLファイル名 |
---|---|
Symfoware | ejbtimer_symfoware.sql |
Oracle | ejbtimer_oracle.sql |
SQL Server | ejbtimer_mssqlserver.sql |
Java DB | ejbtimer_derby.sql |
テーブルに格納するデータについて
以下に、タイマー用のテーブルにアクセスするタイミングについて説明します。
テーブルアクセスのタイミング | 目的 |
---|---|
タイマー登録時 | 当該タイマーのレコードを追加します。 |
コールバックメソッド実行直前 | 当該タイマーがキャンセルされていないかを確認します。 |
コールバックメソッド実行直後 | 当該タイマーのコールバックメソッド実行日時を更新します。 |
タイマーのgetInfoメソッドの初回実行時 | 当該タイマーの情報オブジェクトを読み込みます。 |
タイマーのcancelメソッド実行時 | 当該タイマーのレコードを削除します。 |
TimerServiceのgetTimersメソッド実行時 | Interstage Java EE 6 DASサービスに登録されているタイマーのレコードを読み込みます。 |
Interstage Java EE 6 DASサービス起動時 | 登録済みのタイマーを読み込みます。 |
モジュールの配備解除 (注) | 当該モジュールに関係するタイマーをすべて削除します。 |
モジュールの再配備 (注) | 当該モジュールに関係するタイマーをすべて削除します。 |
モジュールの非活性 (注) | 当該モジュールに関係するタイマーをすべて削除します。 |
注) Interstage Java EE 6 DASサービス停止中状態の場合は、テーブルにアクセスしません。Interstage Java EE 6 DASサービス起動中状態の場合だけテーブルにアクセスし、タイマーを削除します。
Interstage Java EE 6 DASサービス起動時に、異常によりデータソースのアクセスに失敗した場合、サーバーログにEJB5108警告メッセージが出力され、タイマーサービスが無効になります。その場合、EJBタイマーサービスが取得できません。
テーブルに不整合が発生した場合、または不要になったタイマーが残っている場合、DBMSのツールを使用して不要なタイマーの行を検索し削除してください。
以下に、テーブルに格納するデータについて説明します。
カラム名 | データの値 | データ内容の説明 |
---|---|---|
TIMERID | 文字列 | Interstage Java EE 6 DASサービスのインスタンス名を含む内部IDです。 |
OWNERID | 文字列 | Interstage Java EE 6 DASサービスのインスタンス名です。 |
CREATIONTIMERAW | ミリ秒 (注) | タイマーの生成日時です。 |
BLOB | バイナリ | タイマー生成時にcreateTimerメソッドの最終引数で渡す情報オブジェクトです。 |
CONTAINERID | 数値 | TimedObjectを実装するBeanの内部IDです。 |
STATE | 数値 | タイマーの状態です。
|
PKHASHCODE | 数値 | 内部コードです。 |
INTERVALDURATION | ミリ秒 | コールバック処理を繰り返し実行する場合の配信間隔です。 |
INITIALEXPIRATIONRAW | ミリ秒 (注) | 初回のコールバック処理実行の日時です。 |
LASTEXPIRATIONRAW | ミリ秒 (注) | 前回のコールバック処理実行の日時です。 |
SCHEDULE | 文字列 | @Scheduleアノテーションで利用する情報オブジェクトです。@ScheduleアノテーションについてはEJB規約を参照してください。 |
APPLICATIONID | 数値 | Beanの内部IDです。 |
注) 日時設定は、1970年1月1日 0:00:00からのミリ秒
タイマーサービスの設定について
EJBタイマーサービスのタイマーデータソースはasadminコマンドのget/setサブコマンドを使用して設定できます。詳細は、「9.1 asadmin」を参照してください。
タイマーの正確性と処理遅延時の動作
負荷が集中するとタイマーの開始時間がずれる場合があります。
タイマーの処理がすぐに完了せず、後続のタイマーの実行時間が来た場合、後続のタイマーは実行中のタイマーの完了を待ちます。実行中のタイマーが完了後、実行予定時刻が超過しているタイマーは、ただちに実行されます。一定間隔で実行するタイマーの場合、実行予定時刻を越えている処理分連続して実行されます。