【问题标题】:Singleton with cluster带集群的单例
【发布时间】:2016-11-11 02:20:56
【问题描述】:

我有这样的课:

@Singleton
public class RecoveryWorker {
    @Schedule(minute = "*/1", hour = "*", persistent = false)
    public void run() {
        // heavy db queries ~ 2sec
        ...
    }
    ...
}

有 2 个 wildfly 实例具有此单例并使用相同的 oracle 数据库

有时我有错误:

RROR [org.jboss.as.ejb3](EJB 默认值 - 10)JBAS014120:为计时器调用超时时出错:[id=66ed65c4-3a2d-4343-870d-5f7a46a7742c timedObjectId=com.package.Worker 自动计时器? :true persistent?:false timerService=org.jboss.as.ejb3.timerservice.TimerServiceImpl@222950e6 initialExpiration=null intervalDuration(in milli sec)=0 nextExpiration=Wed Jun 15 00:01:00 CEST 2016 timerState=IN_TIMEOUT info=null : javax.ejb.ConcurrentAccessTimeoutException: JBAS014373: EJB 3.1 PFD2 4.8.5.5.1 org.jboss.invocation.InterceptorContext$Invocation@ead4bd3 上的并发访问超时 - 无法在 5000MILLISECONDS 内获得锁定

我想知道这个阻塞是如何发生的(Oracle 有一种机制来阻塞表或其他东西?)一次在几个实例中运行一个单例的最佳实践是什么?

【问题讨论】:

标签: java oracle jakarta-ee jboss singleton


【解决方案1】:

@Singleton 只是 JVM 的单例,不能保证它一次只能在一个实例上运行。

JBAS014120 是因为@Singleton 合约,你的计时器是每一分钟。在您的情况下,我想有时“繁重的数据库查询”可能会运行更长时间,并且会启动另一个单例,因为您没有将锁定权限设置为 READ 对单例的每次调用都会被合同阻止。

如果您需要集群范围的单例,您应该查看快速入门。 我已经编写了 cluster-ha-singleton,这正是您的用例的示例。 https://github.com/wildfly/quickstart 它将选择一个节点并仅在其中一个集群节点上启动计划,以防节点崩溃,它将进行故障转移。

【讨论】:

    猜你喜欢
    • 2013-01-17
    • 2019-03-19
    • 2015-03-13
    • 2010-11-14
    • 1970-01-01
    • 1970-01-01
    • 2016-12-08
    • 1970-01-01
    • 2016-07-13
    相关资源
    最近更新 更多