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



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

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

以下狙击手应该能够给你一个更清晰的画面:

定时器实现:

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();
  }
}

(重新)部署后,一切都很好。但在重启后,玻璃鱼(2.1)给了我们以下信息:

Rescheduling missed expiration for periodic timer ...

我们如何避免这种行为,如何保证计时器只启动一次?

我们必须尝试制作一个注入定时器服务的无状态bean,以便为当前可用的定时器提供服务。但是,将从容器重新安排的计时器没有出现在该列表中,因为容器在整个应用程序初始化结束时重新安排了持久计时器。

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

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

我也遇到过类似的问题。。。。为了确保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()开始时,我将变量ENABLE_TIMER设置为false,在结束时ENABLE_TIMER设置为true

相关内容

  • 没有找到相关文章

最新更新