2013-05-28 41 views
6

Tôi cố lưu kết quả của quy trình đăng nhập để thống kê cơ sở dữ liệu không đồng bộ để tiết kiệm thời gian trong phương thức đăng nhập. Nhưng bằng cách nào đó, quá trình đăng nhập mất nhiều thời gian hơn nếu tôi thêm một thread.sleep vào phương thức async. Tại sao vậy? Tôi nghĩ rằng phương pháp xác thực sẽ không chờ đợi cho các writeResultToStats methode để kết thúc.Phương thức gọi Không đồng bộ trong 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

Tôi nghĩ rằng bạn cần phải thoát ra khỏi phương pháp không đồng bộ vào ejb khác. Vì nó bây giờ, nó sẽ chỉ được xử lý như một phương pháp gọi địa phương –

+0

Hãy để tôi thử điều này và lấy lại cho bạn –

+0

Nó hoạt động. Cảm ơn. –

Trả lời

9

Cố gắng tách phương pháp không đồng bộ thành một phân đoạn riêng biệt. Các phương thức được gọi từ bên trong cùng một ejb sẽ được xử lý giống như các lời gọi phương thức cục bộ. Vùng chứa không có khả năng chặn cuộc gọi phương thức.

EJB-Chú thích chỉ phát khi cuộc gọi được thực hiện bởi vùng chứa.

Alternative

Bạn có thể có phương pháp trong EJB tương tự, nhưng chắc chắn rằng bạn sử dụng giao diện Local EJB để tra cứu các đậu và truy cập vào methord.

6

Hãy xem ví dụ this - nó cho thấy rằng Bạn không cần phải tạo EJB riêng biệt.

Nếu bạn có một bean có cả phương thức đồng bộ và không đồng bộ, không thể gọi phương thức không đồng bộ từ bên trong phương thức đồng bộ vì vùng chứa sẽ không chặn nó.

Nhưng thay vì tạo đậu khác, bạn có thể gọi phương thức đậu không đồng bộ thông qua các 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

Lưu ý rằng các câu trả lời chỉ có liên kết không được khuyến khích, các câu trả lời SO phải là điểm kết thúc của một tìm kiếm cho một giải pháp (so với một điểm dừng khác của các tham chiếu, có xu hướng bị cũ theo thời gian). Vui lòng xem xét thêm bản tóm tắt độc lập tại đây, giữ liên kết dưới dạng tham chiếu. – kleopatra

Các vấn đề liên quan