Java Timer Service多次运行

时间:2016-08-04 12:52:33

标签: java-ee timer scheduling

我创建了一个函数doWork(),它计划每天凌晨1点运行,功能如下:

@Schedule(hour = "1", persistent = false)
    public void doWork()
    {
        System.out.println("Starting .....\nTIME: " + System.currentTimeMillis());
        System.out.println("this : " + this);

        //Some code here, if-conditions and try/catch blocks. No loops

        System.out.println("Exiting .....\nTIME: " + System.currentTimeMillis());
        System.out.println("this : " + this);
    }

问题是此功能不止一次运行,而不是按计划运行。

一旦我创建它,它就完全按预期运行(每天凌晨1:00:00)。几天后,它开始在1:03:00运行(这没有任何意义,因为它是非持久性的,并且服务器中没有任何停机时间)。之后,该功能开始运行不止一次,间隔时间间隔很短(秒差)

有谁知道可能导致这种情况的原因,还是告诉我可以采取哪些措施来解决这个问题?

[编辑]: 环境细节

Application Server:WebSphere Application Server 8.5.5

IDE:Rational Application Developer 9.1

数据库管理系统:IBM DB2 10.1

1 个答案:

答案 0 :(得分:1)

我相信您正在观察试图重试失败的doWork()电话的容器。

EJB计时器服务是事务性的。

如果执行timeout方法会抛出任何运行时异常,那么事务将被回滚,容器将再次尝试执行timeout方法。请参见第18.2.8节“EJB 3.1规范的事务”。

此外,如果事务超时到期,某些实现将仅标记当前事务以进行回滚并继续处理。这将导致计时器调用最终失败,并将尝试重试。

此重试机制未明确指定,实际行为因实现而异。有些人将永远重试,其他人将在经过一些尝试后放弃。例如,WebSphere提供了一种指定重试策略的方法。请参阅Creating timers using the EJB timer service for enterprise beans

最后,如果您的应用程序在多个节点上运行,那么您可能每个服务器实例都运行一个计时器。根据§18.2.3规范的非持久性定时器:

  

对于自动非持久性计时器,容器在应用程序初始化期间为每个分布容器的JVM创建一个新的非持久性计时器。

如果这些都执行相同的任务,那么这可能会导致足够的混乱,从而产生错误,回滚和后续重试。

相关问题