2013-05-28 12 views
6

Cerco di salvare il risultato di un processo di accesso per le statistiche nel database in modo asincrono per risparmiare tempo durante il metodo di accesso. Ma in qualche modo il processo di login richiede più tempo se aggiungo un thread.sleep al metodo asincrono. Perché? Ho pensato che il metodo di autenticazione non aspetterà il completamento del metodo writeResultToStats.Metodi di chiamata Asincrono in 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

Penso che avete bisogno di rompere il metodo asincrono in un altro EJB. Come ora, sarà gestito come invocazione di un metodo locale –

+0

Lasciami provare questo e torna a te –

+0

Funziona. Grazie. –

risposta

9

Provare a scomporre il metodo asincrono in un ejb separato. I metodi richiamati dallo stesso ejb verranno gestiti proprio come le invocazioni del metodo locale. Il contenitore non è in grado di intercettare la chiamata al metodo.

EJB-Annotazioni è solo in gioco quando l'invocazione viene eseguita dal contenitore.

alternativa

Si può avere il metodo nello stesso EJB, ma assicuratevi di utilizzare l'interfaccia locale EJB di ricercare il fagiolo e accedere alla methord.

6

Dai un'occhiata all'esempio this - mostra che non è necessario creare un EJB separato.

Se si dispone di un bean con metodi sincroni e asincroni, non è possibile chiamare il metodo asincrono da quello sincrono perché il contenitore non lo intercetterà.

Ma invece di creare un altro bean, è possibile chiamare il metodo di fagioli asincrona attraverso la SessionContext:

@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

Si noti che le risposte di solo collegamento sono scoraggiate, pertanto le risposte dovrebbero essere il punto finale di una ricerca di una soluzione (rispetto a un'altra sosta di riferimenti, che tende a diventare obsoleta nel tempo). Si prega di considerare l'aggiunta di una sinossi autonoma qui, mantenendo il collegamento come riferimento. – kleopatra