6

我在 Wildfly 10.10 中运行的单例 EJB 中有一个 EJB 计时器计划:

@Singleton
@Startup
@ConcurrencyManagement(ConcurrencyManagementType.BEAN)
public class MySingletonBean {

    public method() {
        //uses synchronization primitives to fine control the concurrent access
    }

    @Schedule(hour = "*", minute = "*", second = "*", persistent = false)
    public void update() {
        //each 120 seconds update method timeouts and the overlapping/log message occurs
    }
}

update() 模型中的任务运行平稳,大部分时间不到 1 秒。但是每2分钟,由于业务需要,方法超时时间超过1秒。

问题:

Wildfly 每 2 分钟输出一条日志消息,例如:

(EJB 默认值 - 1) WFLYEJB0043:计时器 [] 的先前执行仍在进行中,跳过此重叠的计划执行在:。

我很清楚该消息的含义:上一个计时器在下一次执行开始之前没有完成并且发生重叠。

此外,重叠在更新的底层数据结构中引发了并发问题。

我的问题:

1 - 在计时器很慢的情况下如何丢弃下一个计划以避免重叠/并发更新?

2 - 如果不可能丢弃重叠的时间表,如何避免日志消息?

顺便说一句,我考虑将更新方法分成两个不同的时间表(1 秒和 120 秒)。但是打破更新方法意味着过度打破更新下的整个数据结构,至少在目前看来有点复杂和不可行。

任何帮助表示赞赏!

4

2 回答 2

3

我同意 dgebert,因为默认的 ConcurrencyManagement 是容器管理的,默认锁是写的,除非你有一个集群。在集群中,每个节点都有自己的单调和锁管理。如果你没有为定时器服务配置一个中心数据库,所有节点都将被执行并在底层数据结构中引发并发问题。

于 2018-09-11T06:44:03.113 回答
2

你的“定时器”豆是哪种豆?我认为将其设为@Singleton 就足以满足您的情况。如果它是单例,则无法通过多个线程访问该方法。

于 2017-10-25T10:27:22.483 回答