0

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

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

以下片段应该可以为您提供更清晰的画面:

定时器实现:

public class TimerFacade {

  @Resource
  protected TimerService timerService;

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

初始化小服务程序:

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,以让我们提供当前可用的计时器。但是将从容器中重新安排的计时器不会出现在此列表中,这会导致容器在整个应用程序初始化结束时重新安排持久化的计时器。

4

2 回答 2

1

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

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

于 2012-07-26T10:10:16.213 回答
0

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

@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() 的开始,我将变量 ENABLE_TIMER 设置为 false,最后 ENABLE_TIMER 设置为 true

于 2014-12-23T08:51:26.867 回答