2013-05-28 1 views
6

Я пытаюсь сохранить результат процесса входа в систему для статистики в базе данных асинхронно, чтобы сэкономить время во время метода входа. Но почему-то процесс входа в систему занимает больше времени, если я добавляю thread.sleep к методу async. Почему это? Я думал, что метод аутентификации не будет ждать завершения метода 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-Аннотации только в игре, когда вызов осуществляется контейнером.

Alternative

Вы можете иметь метод в том же EJB, но убедитесь, что вы используете локальный интерфейс EJB для поиска бина и получить доступ к Methord.

6

Посмотрите на пример this - он показывает, что вам не нужно создавать отдельный EJB.

Если у вас есть компонент, который имеет как синхронные, так и асинхронные методы, асинхронный метод нельзя вызывать из синхронного, потому что контейнер не будет его перехватывать.

Но вместо того, чтобы создать еще один компонент, вы можете вызвать асинхронный метод боб через 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

Обратите внимание на то, что ссылки только для ответов не приветствуются, ответы SO должны быть конечной точкой поиска решения (по сравнению с еще одной остановкой ссылок, которые со временем устаревают). Пожалуйста, подумайте о добавлении отдельного резюме здесь, сохранив ссылку в качестве ссылки. – kleopatra