2014-02-20 86 views
7

這是一個非常簡單的問題,但我無法確定它發生的原因。 我有一個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秒即

(EJB default - 1) 
(EJB default - 2) 
(EJB default - 3) 
(EJB default - 4) 

等的間隙10個調度實例同時執行。當我把代碼中的一個冗長的操作中,(EJB default - 1)是不完整的,並且當(EJB default - 2)試圖執行它給了我一個錯誤說:

JBAS014373:對組織EJB 3.1 PFD2 4.8.5.5.1同時訪問超時。 [email protected] - 無法內5000毫秒

首先獲得鎖,我如何才能避免多個EJB實例調度在時間執行? 二,「5000MILLISECONDS以內無法獲得鎖定」的處理是什麼?如何避免?

對於出現的超時錯誤,我發現在JBOSS隊列中有很多門票,如here所述。


編輯

中添加了最新的註解,因此它是可讀的代碼:

@圖莎爾-46835,你可以闡述在您的解決方案,也許我們展示的片段是什麼你做到了? - rtcarlson 10月2日在'14 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()); 
} 

回答

6

首先,我怎樣才能避免多個EJB實例調度可一次執行 ?

您正在創建持久定時器。因此,在指定的時間間隔之後,它將創建新的隊列&,等待前一個隊列完成執行。

我推測,在您重新啓動後,所有排隊的定時器都會超時&服務器會創建多個實例,因爲它們是持久的。

二,「 5000MILLISECONDS」無法獲得鎖定,怎樣才能避免它?

它是單例,所有方法默認都有鎖式寫入,所以一次只能有一個線程執行。所以別人會得到超時異常/無法獲得鎖等。如你所說,有一個漫長的過程。

+1

@ Tushar-46835,你能解釋一下你的解決方案,也許向我們展示你所做的一小部分嗎? – rtcarlson

+0

@rtcarlson:下面是修復我的問題的代碼片段: 資源 TimerService timerService; Schedule(persistent = false,minute =「*/30」,hour =「*」) \t public void checkQueueState(){ \t \t dt = new DataAccessFactory(); \t \t excvo = dt.canExecute(); \t \t dt = null; \t \t available = excvo.isExecuteReady(); \t \t如果(有){ \t \t \t timerService.createSingleActionTimer(新的Date(),新TimerConfig( \t \t \t \t \t空,假)); \t \t} \t} \t超時 \t私人無效generateReport(定時器定時){ \t \t logger.info( 「!! - 超時這裏援引」 +新的Date()); \t} – TusharPanda