23

時々コンテナによって呼び出される@Scheduleで注釈が付けられたメソッドがあります。

@Schedule(second = "*/5", minute = "*", hour = "*", persistent = false)
public void myTimerMethod() throws Exception {
    ...
}

問題は特定の条件にあります。このメソッドで例外をスローして、進行中のトランザクションをロールバックさせたいと考えています。しかし、これを2回以上行うと、タイマーが消去され、呼び出されなくなります。

INFO: EJB5119:Expunging timer ['68@@1359143163781@@server@@domain1' 'TimedObject = MyBean' 'Application = My-War' 'BEING_DELIVERED' 'PERIODIC' 'Container ID = 89072805830524936' 'Fri Jan 25 21:49:30 CET 2013' '0' '*/5 # * # * # * # * # * # * # null # null # null # true # myTimerMethod # 0' ] after [2] failed deliveries

domain.xmlでタイマーの再スケジュールを構成できることはわかっています。

<domains>
    ...
    <configs>
        <config>
            ...
            <ejb-container session-store="${com.sun.aas.instanceRoot}/session-store">
               <ejb-timer-service>
                     <property name="reschedule-failed-timer" value="true"></property>
                </ejb-timer-service>
            </ejb-container>
            ...
        </config>
    </configs>
    ...
</domains>

しかし、私の質問は、アプリケーションをデプロイするときにこの設定を構成できますか?

で見つかりません:

glassfish-resources.xml
glassfish-ejb-jar.xml
glassfish-web.xml

プログラムでそれを行う方法はありますか?

(サーバーを構成するのではなく、このようなサーバー構成を構成ファイルに入れることの背後にある私の理論的根拠は、私のアプリがGlassfishの新規インストールに直接インストールできるようにするためです)

4

2 に答える 2

26

私は別のアプローチを使用します。

スケジュールされたメソッドから直接例外をスローする代わりに、次のように間接的なレベルを導入してみてください。

...
@Inject RealWorkHere realImplementation;

@Schedule(second = "*/5", minute = "*", hour = "*", persistent = false)
public void myTimerMethod(){
  try{
     realImplementation.myTimerMethodImpl()
  }catch (Exception x){
   // hopefully log it somewhere
  }
}
...

RealWorkHere次のように、実際の実装を持つ Bean はどこにありますか。

@Stateless
public class RealWorkHere{
   @TransactionAttribute(REQUIRES_NEW)
   public void myTimerMethod() throws Exception {

   }
}

これには次の利点があります。

  • コンテナで開始されたトランザクションで例外をスローしない (したがって、消去を回避する)
  • 例外のロギングの改善
  • 「実際の」商取引の明確な境界

こちらもご覧ください

于 2013-01-28T08:46:29.857 に答える