在glassfish中多次调用EJB 3.0计时器bean超时

时间:2012-07-26 08:14:15

标签: ejb-3.0 java-ee-5 glassfish-2.x

我们必须实现EJB 3.0计时器,并采用以下方法:

  • 我们创建了@Stateless bean并使用@Resource注释注入TimerService
  • 我们已经实现了一个在启动时调用初始化方法的servlet

以下snipets应该能够为您提供更清晰的图片:

计时器实现:

public class TimerFacade {

  @Resource
  protected TimerService timerService;

  public void createTimer() {
    timerService.createTimer(startTime, intervall, ident);
  }
}

init servlet:

public class InitServlet extends HttpServlet {
  @EJB
  private transient ITimerFacade timerFacade;

  @Override
  public void init(final ServletConfig config) throws ServletException {
    timerFacade.createTimer();
  }
}

在(重新)部署之后,一切都很好。但重新启动后,glassfish(2.1)会给我们以下消息:

Rescheduling missed expiration for periodic timer ...

我们怎样才能避免这种行为?我们怎样才能保证定时器只启动一次?

我们必须尝试使用​​注入的计时器服务来创建一个无状态bean,让我们给出目前可用的计时器。但是,将从容器中重新安排的计时器不会出现在此列表中,导致容器在整个应用程序初始化结束时重新安排持久计时器。

2 个答案:

答案 0 :(得分:1)

EJB计时器是持久的,这意味着如果您没有取消计时器,它将在服务器启动后继续工作。

您应该在应用程序关闭时取消计时器(不确定如何在glassfish中执行此操作),或者在创建新计时器之前检查该计时器是否已存在。

答案 1 :(得分:0)

我有类似的问题....为了确保ObjectTimer在运行时使用了一种信号量,我在@Timeout方法中使用的静态布尔变量ENABLE_TIMER:

@Timeout
public void timerMethod(Timer timer) {
    try{
    if (ObjectModelSessionBean.ENABLE_TIMER ) {
        timerMethod();
    } else {
        LOGGER.info("timer is temporary disabled - waiting....);
    }
    }catch (Exception ex){
         LOGGER.severe("- Eccezione.   "+ex.toString());
    }
}

在timerMethod()的beginnig我将变量ENABLE_TIMER设置为false,最后将ENABLE_TIMER设置为true