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

Java 计时器正在创建多个计时器实例,java,jakarta-ee,jboss,ejb-3.0,ejb-timer,Java,Jakarta Ee,Jboss,Ejb 3.0,Ejb Timer,我想这是一个非常简单的问题,但我不明白为什么会发生这种情况。 我有一个EJB计时器的实现,它使用@Singleton注释,即Singleton计时器 我已将其设置为每5分钟运行一次。代码如下所示: @Singleton @TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED) public class Scheduler { private static final double timerVar = Math.rando

我想这是一个非常简单的问题,但我不明白为什么会发生这种情况。 我有一个EJB计时器的实现,它使用@Singleton注释,即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默认值-1)
不完整,当
(EJB默认值-2)
尝试执行时,会出现一个错误,提示:

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

首先,如何避免一次执行多个EJB调度程序实例? 第二,“在5000毫秒内无法获得锁”的处理是什么?如何避免

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


编辑

在最新注释中添加了代码,以便可读:


@Tushar-46835,你能解释一下你的解决方案吗?也许给我们看一下你所做的事情的片段rtcarlson 2014年10月2日20:12


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

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

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

我假定,在重新启动之后,所有排队的计时器都已超时&服务器将创建多个实例,因为它们是持久的

第二,"内得不到锁"是怎么回事? “5000毫秒”,我如何避免它


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

@Tushar-46835,您能否详细说明您的解决方案,或者向我们展示您所做的工作的片段?@rtcarlson:以下是修复我的问题的代码片段:Resource TimerService TimerService;计划(persistent=false,minute=“/30”,hour=“)public void checkQueueState(){dt=new DataAccessFactory();excvo=dt.canExecute();dt=null;available=excvo.isexecuterady();if(available){timerService.createSingleActionTimer(new Date(),new TimerConfig(null,false));}超时专用void generateReport(Timer Timer){logger.info(!!--Timeout在此调用“+new Date());}
 @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()); 
 }