【问题标题】:Ejb Timer throwing javax.ejb.ConcurrentAccessTimeoutException: Unable to get write lock onEjb 计时器抛出 javax.ejb.ConcurrentAccessTimeoutException:无法获得写锁定
【发布时间】:2014-08-17 21:33:18
【问题描述】:

我的应用程序在 tomee 上运行,并且我有 ejb 计时器每两分钟触发一次超时方法。计时器第一次触发了超时方法,并且当计时器第二次尝试触发相同的方法时仍在运行。它抛出了以下异常..

javax.ejb.ConcurrentAccessTimeoutException: Unable to get write lock on 'timeout' method for: com.abc.xyz
        at org.apache.openejb.core.singleton.SingletonContainer.aquireLock(SingletonContainer.java:298)
        at org.apache.openejb.core.singleton.SingletonContainer._invoke(SingletonContainer.java:217)
        at org.apache.openejb.core.singleton.SingletonContainer.invoke(SingletonContainer.java:197)
        at org.apache.openejb.core.timer.EjbTimerServiceImpl.ejbTimeout(EjbTimerServiceImpl.java:769)
        at org.apache.openejb.core.timer.EjbTimeoutJob.execute(EjbTimeoutJob.java:39)
        at org.quartz.core.JobRunShell.run(JobRunShell.java:207)
        at org.quartz.simpl.SimpleThreadPool$WorkerThread.run(SimpleThreadPool.java:560)

我的所有日​​志都被相同的堆栈跟踪填满,并且它会继续发生,直到我停止服务器..

如果 timerservice 已经在运行,我们可以让 timerservice 不触发该方法吗? 或者有没有办法在第一次调用被再次触发之前超时..

谢谢,

【问题讨论】:

    标签: java jakarta-ee timer ejb ejb-3.1


    【解决方案1】:

    如果你想避免多次并行运行,但又想避免调度运行排队,那么我有另一个建议。

    如果前一个仍在运行,我会让计划“跳过”:

    @Singleton
    @Startup
    @ConcurrencyManagement(ConcurrencyManagementType.BEAN)
    public class Example
    {
        private final AtomicBoolean alreadyRunning = new AtomicBoolean(false);
    
        @Schedule(minute = "*", hour="*", persistent = false)
        public void doWork()
        {
            if (alreadyRunning.getAndSet(true)) return;
    
            try
            {
                //  ... your code
            }
            finally
            {
                alreadyRunning.set(false);
            }
        }
    }
    

    【讨论】:

      【解决方案2】:

      您的定时 EJB 是单例 bean 吗? 默认情况下,单例使用容器管理的并发和写锁来保证所有方法的独占访问。

      openejb.xml 为单例 EJB 配置 AccessTimeout。超时之后,您看到的异常将被抛出。也请看这里:http://tomee.apache.org/singleton-beans.html

      解决方案可能是:

      1. 使用无状态会话 bean 作为计时器 bean
      2. 在定时器方法上定义读锁
      3. 不要使用重复计时器,而是在当前执行结束时安排计时器的下一次执行。

      【讨论】:

        猜你喜欢
        • 2013-01-04
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-04-04
        • 1970-01-01
        • 2011-10-26
        • 2014-03-25
        • 1970-01-01
        相关资源
        最近更新 更多