2013-05-28 35 views
6

我嘗試將異步登錄過程的結果保存到數據庫中,以便在登錄方法期間節省時間。但不知何故,如果我添加一個thread.sleep到異步方法登錄過程需要更長的時間。這是爲什麼?我認爲authenticate方法不會等待writeResultToStats方法完成。EJB中的異步調用方法

@Stateless 
    @LocalBean 
    @ConcurrencyManagement(ConcurrencyManagementType.CONTAINER) 
    @TransactionManagement(TransactionManagementType.CONTAINER) 
    public class CustomerBeanTest { 

     @PersistenceContext(unitName = WebPersistenceUnits.QISADS) 
     private EntityManager em_local; 

     @TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED) 
     public void authenticate(Long loginid, String cmppassword) { 
      try { 
       Login l = em_local.find(Login.class, loginid); 
       String s = l.getPassword(); 
       if (!s.equalsIgnoreCase(cmppassword)) 
        throw new PasswordMissmatchException(); 
       writeResultToStats(loginid, true); 
      } catch (PasswordMissmatchException e) { 
       writeResultToStats(loginid, false); 
      } 
     } 

     @Asynchronous 
     @TransactionAttribute(TransactionAttributeType.REQUIRES_NEW) 
     private void writeResultToStats(Long loginID, boolean success) { 

      try { // just for testing 
       Thread.sleep(10000); 
      } catch (InterruptedException e) { 
       // TODO Auto-generated catch block 
       e.printStackTrace(); 
      } 

      LogUtils log = new LogUtils(this); 
      Login l = em_local.find(Login.class, loginID); 
      if (success) { 
       l.setSuccessLast(new Date()); 
       l.setSuccessCount(l.getSuccessCount()+1); 
       log.log(Level.INFO, "Update Login Stat Success [%d, %s, %d]", l.getId(), l.getName(), Thread.currentThread().getId()); 
      } else { 
       l.setFailureLast(new Date()); 
       l.setFailureCount(l.getFailureCount()+1); 
       log.log(Level.INFO, "Update Login Stat Fail [%d, %s, %d]", l.getId(), l.getName(), Thread.currentThread().getId()); 
      } 

     } 

    } 
+1

我認爲你需要打出來的異步方法進入另一個EJB。就像現在一樣,它只是作爲本地方法調用來處理。 –

+0

讓我試試這個並回復你 –

+0

它的工作原理。謝謝。 –

回答

9

嘗試將異步方法分解爲單獨的ejb。從同一個ejb中調用的方法將像本地方法調用一樣進行處理。容器不能攔截方法調用。

EJB-Annotations僅在容器完成調用時才起作用。

替代

你可以在同一個EJB方法,但要確保你使用EJB本地接口來查找bean並訪問methord。

6

看一看this示例 - 它表明您不需要創建單獨的EJB。

如果您有一個同時擁有同步方法和異步方法的bean,則無法在同步方法內調用異步方法,因爲該容器不會攔截它。

但不是創造另一個bean,你可以調用通過SessionContext異步Bean方法:

@Stateless 
public class OrderProcessorBean { 
    @Inject 
    SessionContext ctx; 
    //synchronous method invoked from EJB call outside this class 
    public void synch() { 
     //call asynch method 
     ctx.getBusinessObject(OrderProcessorBean.class).asynch(); 
    } 

    @Asynchronous 
    public void asynch() { 
     //asynch logic 
    } 
} 
+2

請注意,只有鏈接的答案是不鼓勵的,所以答案應該是搜索解決方案的終點(而另一個引用的中途停留時間往往會過時)。請考慮在此添加獨立的摘要,並將鏈接保留爲參考。 – kleopatra