我有一个EJB计时器的实现,它使用@Singleton注释,即单例计时器.
我每隔5分钟就开始运行一次.代码看起来像这样:
@Singleton @TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED) public class Scheduler { private static final double timerVar = Math.random() * 33; static Logger logger = Logger.getLogger("Scheduler"); @Schedule(second = "*",minute = "*/5",hour = "*",persistent = true) public void doWork() { logger.log(Level.INFO,"timer value for this session : " + timerVar); } }
当进程运行时,它在1秒的间隙内同时执行10个调度程序实例,即
(EJB default - 1) (EJB default - 2) (EJB default - 3) (EJB default - 4)
等等.当我在代码中放置一个冗长的操作时,(EJB default – 1)不完整,当(EJB default – 2)尝试执行时,它给出了一个错误说:
JBAS014373: EJB 3.1 PFD2 4.8.5.5.1 concurrent access timeout on org.jboss.invocation.InterceptorContext$Invocation@1b83ad52 – could not obtain lock within 5000 MILLISECONDS
首先,如何避免一次执行多个EJB调度程序实例?
第二,什么是“无法在5000MILLISECONDS内获得锁定”的交易,我该如何避免呢?
对于我得到的超时错误,我发现JBOSS队列中有很多票据,如here所述.
编辑
@Tushar-46835,could you expound upon your solution,maybe show us the snippet of what you did? – rtcarlson Oct 2 ’14 at 20:12
@rtcarlson : Here is the code snippet which fixed my issues:
@Resource TimerService timerService; @Schedule(persistent = false,minute = "/30",hour = "") public void checkQueueState() { dt = new DataAccessFactory(); excvo = dt.canExecute(); dt = null; available = excvo.isExecuteReady(); if (available) { timerService.createSingleActionTimer(new Date(),new TimerConfig(null,false)); } } @Timeout private void generateReport(Timer timer) { logger.info("!!--timeout invoked here " + new Date()); }
解决方法
First,how can I avoid multiple EJB scheduler instances to be executed
at a time?
您正在创建持久计时器.因此,在指定的间隔后,它将创建新的&将它们排队,等待前一个完成执行.
我想,在你重新启动之后,所有排队的计时器都有超时的时间.服务器将创建多个实例,因为它们是持久的.
Second,what is the deal with “could not obtain lock within
5000MILLISECONDS” and how can I avoid it?
它是单例,默认情况下所有方法都有锁类型写,因此一次只执行一个线程.因此,如你所说,其他人将获得超时异常/无法获得锁定等,这是一个漫长的过程.