gpt4 book ai didi

jakarta-ee - 多次运行的 Java 定时器服务

转载 作者:行者123 更新时间:2023-12-04 01:14:11 25 4
gpt4 key购买 nike

我创建了一个函数 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 应用服务器 8.5.5

IDE:Rational Application Developer 9.1

数据库管理系统:IBM DB2 10.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 :

For automatic non-persistent timers, the container creates a new non-persistent timer during application initialization for each JVM across which the container is distributed.



如果这些都在执行相同的任务,那么很可能会造成足够的困惑以产生错误、回滚和随后的重试。

关于jakarta-ee - 多次运行的 Java 定时器服务,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38767888/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com