简体   繁体   English

回滚时取消ejb计时器

[英]Cancel ejb timer on rollback

Is there any way to make sure a periodic (every 10 seconds) and persistent timer is cancelled when an exception occurs? 有什么方法可以确保在发生异常时取消定期(每10秒)和持久性计时器? The implementation of the @Timeout method is something like this (simplified from legacy code): @Timeout方法的实现类似于以下内容(从旧版代码简化):

@Timeout
@TransactionAttribute(REQUIRES_NEW)
public void onTimeout(Timer timer) {
    try {
        doSomeBusinessLogic();
    } catch (Exception e) {
        // throwing this exception makes sure rollback is triggered
        throw new EJBException(e);
    }
}

Upon any exception in doSomeBusinessLogic() , its transaction needs to be rolled back. doSomeBusinessLogic()doSomeBusinessLogic()任何异常时, doSomeBusinessLogic()需要回滚其事务。 This is working fine. 一切正常。 However, I would also make sure that the timer is cancelled. 但是,我还要确保取消计时器。

The straightforward solution is to put timer.cancel() in the catch block. 直接的解决方案是将timer.cancel()放入catch块中。 This is not working, however, because the cancelling will also be rolled back ( JEE6 Turorial ): 但是,这不起作用,因为取消操作也会回滚( JEE6 Turorial ):

An enterprise bean usually creates a timer within a transaction. 企业bean通常在事务中创建一个计时器。 If this transaction is rolled back, the timer creation also is rolled back. 如果回滚此事务,则计时器创建也会回滚。 Similarly, if a bean cancels a timer within a transaction that gets rolled back, the timer cancellation is rolled back. 同样,如果Bean取消了回滚的事务中的计时器,则计时器取消也会回滚。 In this case, the timer's duration is reset as if the cancellation had never occurred. 在这种情况下,重置计时器的持续时间就好像从未发生过取消一样。

How can I make sure that the timer is cancelled (preventing any further timeouts) if an exception/rollback occurs? 如果发生异常/回滚,如何确保取消计时器(防止进一步的超时)? Setting a maximum nuber of retries would also be sufficient, but I don't think this is supported by JBoss. 设置最大重试次数也已足够,但是我不认为JBoss支持这一点。

Application server is JBoss AS 7.2. 应用服务器是JBoss AS 7.2。

  1. You can create new transation (call next EJB) from timer bean 您可以从计时器bean创建新的转换(调用下一个EJB)
  2. You can change TA @TransactionAttribute(NEVER) and create new transation (call next EJB) from timer bean 您可以更改TA @TransactionAttribute(NEVER)并从计时器bean创建新的转换(调用下一个EJB)。

And put timer.cancel() in the catch block 并将timer.cancel()放入catch块中

I also tried solution proposed by Sergey and it seems to work - timer is cancelled. 我还尝试了谢尔盖(Sergey)提出的解决方案,它似乎可以工作-计时器已取消。 Tested on JBoss EAP 6.2. 在JBoss EAP 6.2上测试。 Here is the code I used for testing: 这是我用于测试的代码:

@Stateless
public class TimeoutTest implements TimeoutTestLocal {

@Resource
TimerService timerService;

@Resource
SessionContext sessionContext;

@Timeout
@TransactionAttribute(TransactionAttributeType.NEVER)
public void tmout(javax.ejb.Timer timer) {
    try {
        System.out.println("timout invoked");
        //instead of internal call let's invoke doNothing as
        //this timeout callback is client of TimeoutTest EJB
        //in this way doNothing will be run inside transaction
        TimeoutTestLocal local = sessionContext.getBusinessObject(TimeoutTestLocal.class);
        local.doNothing();  
    } catch (Exception e) {
        timer.cancel();
        System.out.println("Timer cancelled");
    }
}

@Override 
@TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
public void doNothing() {
    throw new EJBException("RE Exception");
}


@Override
public void schedule() {
    timerService.createTimer(5000, 10000, "test");
}
}

I have a similar situation, however canceling the timer in the catch clause seems to work. 我也有类似的情况,但是在catch子句中取消计时器似乎是可行的。 The reason why I need this is to force the container (Wildfly) to not retry a failed timeout. 我之所以需要这样做,是为了强制容器(Wildfly)不要重试失败的超时。

The code looks something like this: 代码看起来像这样:

@Timeout
public void onTimeout(Timer timer) {
    try {
        //the other ejb has @TransactionAttribute(TransactionAttributeType.SUPPORTS)
        doSomeBusinessLogicInSomeOtherEjbThatThrowsEjbException();
    } catch (EJBException e) {
        timer.cancel();
        throw e;//this is not necessary since the EJB context has already getRolledBack = true at this point
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM