【问题标题】:Java Timer Service running multiple timesJava Timer Service 多次运行
【发布时间】:2016-12-10 14:37:17
【问题描述】:

我已经创建了一个函数doWork(),它被安排在每天凌晨1:00运行,函数如下:

@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 开始运行(这没有任何意义,因为它是非持久的,而且服务器也没有停机时间)。之后,该函数开始多次运行,其间的间隔非常短(秒差)

有谁知道这可能是什么原因,或者告诉我我能做些什么来解决它?

[编辑]: 环境细节

应用服务器:WebSphere Application Server 8.5.5

IDE:Rational Application Developer 9.1

数据库管理系统:IBM DB2 10.1

【问题讨论】:

  • 您使用的是哪个应用服务器(和版本)?这可能有助于检查是否存在与该 AS 相关的问题。
  • 您如何记录服务运行的时间?日志输出?系统/服务器时间?
  • @OlivierGrégoire 我正在使用 WebSphere Application Server 8.5.5
  • @kolossus 两次都是根据服务器时间记录的。该方法计划在凌晨 1:00 运行,但由于某种原因,它在随机时间运行,并且运行多次。

标签: jakarta-ee timer scheduling


【解决方案1】:

我相信您正在观察容器尝试重试失败的 doWork() 调用。

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

如果执行超时方法抛出任何运行时异常,则事务将回滚,容器将再次尝试执行超时方法。请参阅 EJB 3.1 规范的 §18.2.8 事务。

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

这种重试机制没有很好地指定,实际行为因实现而异。有些人会永远重试,有些人会在多次尝试后放弃。例如,WebSphere 提供了一种指定重试策略的方法。见Creating timers using the EJB timer service for enterprise beans

最后,如果您的应用程序跨多个节点运行,那么您可能会为每个服务器实例运行一个计时器。根据规范的§18.2.3 Non-persistent Timers:

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

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

【讨论】:

  • 根据日志,doWork()方法第一次运行成功,然后再次运行失败,不断重试。所做的是它需要一个 csv 文件,对其进行解析,从数据库中删除所有内容,然后保存解析的数据。根据日志,第一次尝试成功清空数据库并重新填充,然后该方法再次运行并不断重试,我最终得到一个空数据库。既然第一次尝试成功,我不明白为什么第一次尝试后会再次调用该方法?
  • 在任何人进一步推测之前,您仍然需要提供您的环境的更多详细信息。此外,您如何确定初始交易成功完成 - 即在 doWork() 退出之后?
  • 由于日志记录,我确信它在第一次尝试时成功完成。通过检查数据库日志,我可以看到解析后的 .csv 文件中的记录已成功保存到数据库中。然后它继续重试,删除数据库中的所有内容,最后我得到一个空数据库。并请检查环境细节的编辑
  • 您有多少个服务器实例? EJB 是 @Singleton 还是 @Stateless?
  • 方法执行需要多长时间?
猜你喜欢
  • 2012-02-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-10-07
  • 1970-01-01
  • 2011-01-14
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多