2012-08-16 59 views
1

您好長時間運行的線程在Postconstruct中啓動並定期更新數據庫。EJB 3.1中長時間運行的線程異常StartUp singleton postconstruct方法

貌似這個

public void postconstruct() { 
    Runnable runnable; 
    runnable = new Runnable() { 
     @Override 
     public void run() { 
      int interval = poissonRandomNumber(15); 
      while (true) { 
       try { 
        Map<Account, AccountUpdate> recentUpdates = 
          simulator.getRecentUpdates(tickDAO, securityDAO); 
        for (Map.Entry<Account, AccountUpdate> entry : recentUpdates.entrySet()) { 
         Account account = entry.getKey(); 
         //       String realised = getAccountReturn(parts, account); 
         Account accountByName = accountDAO.findAccountByName(account.getName()); 
         if(accountByName == null ) 
         { 
          account.setAccountId(null); 
          accountByName = accountDAO.create(account); 
         } 
         int realised = new Random().nextInt(50); 
         boolean nextBoolean = new Random().nextBoolean(); 
         realised = nextBoolean == true ? realised : -realised; 
         AccountUpdate accountUpdate = entry.getValue(); 
         accountUpdate.setAccountId(accountByName); 
         accountUpdate.setDateCreated(new Date()); 
         accountUpdate.setUnRealisedPL(new BigDecimal(realised)); 
         accountUpdateDAO.create(accountUpdate); 
        } 
        Thread.sleep(interval); 
       } catch (Exception ex) { 
        Logger.getLogger(ApplicationManager.class.getName()).log(Level.SEVERE, null, ex); 
       } 
      } 
     } 
    }; 
    Thread tickThread = new Thread(runnable); 
    tickThread.start(); 

每當我啓動我得到很多的例外,因爲它看起來像集裝箱還沒有準備好

我需要知道如何最好地使用DAO的應用程序,以及如何檢測所述conytainer是就緒

該異常是如下所示

SEVERE: java.lang.NullPointerException 
at com.sun.ejb.containers.util.pool.NonBlockingPool.returnObject(NonBlockingPool.java:285) 
at com.sun.ejb.containers.StatelessSessionContainer.releaseContext(StatelessSessionContainer.java:602) 
at com.sun.ejb.containers.BaseContainer.postInvoke(BaseContainer.java:2055) 
at com.sun.ejb.containers.BaseContainer.postInvoke(BaseContainer.java:1994) 
at com.sun.ejb.containers.EJBLocalObjectInvocationHandler.invoke(EJBLocalObjectInvocationHandler.java:222) 
at com.sun.ejb.containers.EJBLocalObjectInvocationHandlerDelegate.invoke(EJBLocalObjectInvocationHandlerDelegate.java:89) 
at $Proxy270.create(Unknown Source) 
at ucl.atrade.rnpvms.server.services.ApplicationManager$1.run(ApplicationManager.java:126) 
at java.lang.Thread.run(Thread.java:722) 

SEVERE: javax.ejb.EJBException: Attempt to invoke when container is in Undeployed 
    at com.sun.ejb.containers.BaseContainer.postInvoke(BaseContainer.java:1999) 
    at com.sun.ejb.containers.BaseContainer.postInvoke(BaseContainer.java:1994) 
    at com.sun.ejb.containers.EJBLocalObjectInvocationHandler.invoke(EJBLocalObjectInvocationHandler.java:222) 
    at com.sun.ejb.containers.EJBLocalObjectInvocationHandlerDelegate.invoke(EJBLocalObjectInvocationHandlerDelegate.java:89) 
    at $Proxy265.findSecurityBySymbol(Unknown Source) 
    at ucl.atrade.rnpvms.server.datafeed.AccountUpdateSimulator.getRecentUpdates(AccountUpdateSimulator.java:74) 
    at ucl.atrade.rnpvms.server.services.ApplicationManager$1.run(ApplicationManager.java:108) 
    at java.lang.Thread.run(Thread.java:722) 
+1

http://docs.oracle.com/javaee/6/tutorial/doc/bnboy.html,恕我直言,由JAVA EE中的應用程序代碼啓動長時間運行的線程是非常糟糕的做法。 – esej 2012-08-16 09:08:58

+0

爲什麼問題的標題是關於取消部署,問題是關於啓動?如果您的EJB需要定期更新,那麼爲什麼不使用EJB定時器,這是管理EJB內部線程的最佳方式(也許是唯一允許的方式)?還請記住在您發佈的代碼中插入註釋/成員實例 – perissf 2012-08-16 09:10:21

+0

我已更新代碼以反映完整方法。我無法使用A計時器,因爲帳戶更新是隨機的。 – 2012-08-16 09:24:11

回答

2

在此link作爲很好的解釋,

EJB規範分配給EJB容器管理線程的責任。允許企業bean實例創建和管理線程會干擾容器控制其組件生命週期的能力。

這意味着在您的EJB中使用Runnable是不可行的。

如果你想運行給定頻率的代碼,你可以使用Timer Service

如果你需要運行一些代碼時更新到數據庫做的其他方式,即異步,你必須使用其他技術,如JMS或數據庫觸發器或持久化上下文共享/傳播,或Entity Listeners,取決於您的應用程序的要求。

相關問題