Ejb Timer抛出javax.ejb.ConcurrentAccessTimeoutException:无法获得写锁定

sam*_*ath 3 java ejb timer java-ee ejb-3.1

我的应用程序运行在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)
Run Code Online (Sandbox Code Playgroud)

我的所有日​​志都填充了相同的堆栈跟踪,并一直发生,直到我停止服务器..

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

谢谢,

Rob*_*zer 5

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

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

解决方案可能是:

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