Timer正在创建多个计时器实例

Tus*_*nda 7 java jboss java-ee ejb-3.0 ejb-timer

这是一个真正简单的问题,我想但是我无法弄清楚为什么会发生这种情况.我有一个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);
    } 
}
Run Code Online (Sandbox Code Playgroud)

当进程运行时,它在1秒的间隙中同时执行10个调度程序实例

(EJB default - 1)
(EJB default - 2)
(EJB default - 3)
(EJB default - 4)
Run Code Online (Sandbox Code Playgroud)

等等.当我在代码中放置一个冗长的操作时,它(EJB default - 1)是不完整的,当(EJB default - 2)尝试执行它时会给我一个错误说:

JBAS014373:EJB 3.1 PFD2 4.8.5.5.1 org.jboss.invocation.InterceptorContext$Invocation@1b83ad52上的并发访问超时 - 无法在5000 MILLISECONDS内获取锁定

首先,如何避免一次执行多个EJB调度程序实例?第二,什么是"无法在5000MILLISECONDS内获得锁定"的交易,我该如何避免呢?

对于我得到的超时错误,我发现在这里提到的JBOSS队列中有很多票证.


编辑

在最新评论中添加了代码,因此它是可读的:

@ Tushar-46835,你能解释一下你的解决方案,也许可以告诉我们你做了什么的片段? - rtcarlson 2014年10月2日20:12

@rtcarlson:这是修复我的问题的代码片段:

 @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()); 
 }
Run Code Online (Sandbox Code Playgroud)

Nay*_*kar 6

首先,如何避免一次执行多个EJB调度程序实例?

您正在创建持久计时器.因此,在指定的间隔之后,它将创建新的并将它们排队,等待前一个完成其执行.

我认为,重新启动后,所有已排队的计时器都会超时,并且服务器会创建多个实例,因为它们是持久的.

第二,什么是"无法在5000MILLISECONDS内获得锁定"的交易,我该如何避免呢?

它是单例,默认情况下所有方法都有锁类型写,因此一次只执行一个线程.因此,其他人将获得超时异常/无法获得锁定等,正如您所说,有一个漫长的运行过程.