4

次のシナリオでは、単純なタイマー タスクを実装する必要があります。

method1(){  
.....  
   if(success){  
      trigger method2 for next 30 min every 15 sec  
   }  
}

java.util.Timer と java.util.TimerTask を使用してこのコードを実装し、正常に動作しています。ただし、私のコードは最終的に Glassfish サーバーに Web サービスとしてデプロイされます。したがって、タイマーを介して間接的にスレッドを使用しているため、グラスフィッシュコンテナーが原因で問題が発生するかどうかを知りたいです。

また、EJB タイマー Bean を使用する必要があるかどうかもわかりません。誰かが両方のアプローチの長所と短所を教えてもらえますか?

4

2 に答える 2

5

EJB 仕様では、ユーザー コード (またはサード サイド コード) のスレッド化について警告しています。

エンタープライズ Bean は、スレッドの管理を試みてはなりません。エンタープライズ Bean は、スレッドの開始、停止、一時停止、再開、またはスレッドの優先度や名前の変更を試みてはなりません。エンタープライズ Bean は、スレッド グループの管理を試みてはなりません。( 21.2.2 プログラミング制限、EJB 3.1 仕様)

EJB タイマー Bean が推奨されます。

于 2013-01-22T04:48:26.680 に答える
2

ほとんどすべての EJB と同様に、2 つの手法の最大の違いはトランザクションです。タイマー EJB は、まあ、EJB であるため、各呼び出しは一意のトランザクションになり、コンテナーはそれらすべての詳細を管理します。

スレッドは、特に EJB 内から作成された場合、未確定のトランザクション状態になります。ほとんどのコンテナーは、現在実行中のスレッド、特にトランザクション状態に多くのコンテキストを関連付けます。これが (とりわけ)、EJB コンテナーで自己作成スレッドが悪い考えである理由の 1 つです。コンテナーのコンテキスト情報が欠落または破損している可能性があります。

EJB タイマーの場合、15 秒ごとに起動するタイマーを簡単に作成できますが、追跡して 30 分後に手動でキャンセルする必要があります。ScheduleExpression を使用して「30 分間は 15 秒ごと」のルールを表現できますが、最後にタイマーをキャンセルする必要があります (率直に言って、その式を適切に作成するには、より多くの作業が必要になります)。タイマー情報に開始時刻を入れるだけで、開始時刻を通知する方が簡単です。その後、最後の実行で終了することができます。

Java EE 6 より前の時代、タイマーは永続的であり、コンテナーの再起動後も存続しました (ただし、アプリケーションの再デプロイではありません)。現在、永続性はオプションであるため、その詳細に注意を払う必要があります。

このメソッドが (EJB 層ではなく) Web 層からトリガーされる場合、スレッド化の制限が緩和されるか、Quartz タイマーを使用できます。

しかし、EJB タイマーはかなり優れており、Java EE 6 の方が適しています。は EJB タイマーを使用しますが、私はそれらに慣れており、使いにくい Java EE 6 以前のものをしばらく使用してきました。このプロセス全体で EJB 層にいるのであれば、私は間違いなくそれらを使用します。

于 2013-01-22T05:11:23.763 に答える