2010-08-02 1 views
0

[내 설정 : 자바 EE 6 응용 프로그램, EJB3.1과는 CDI/용접, JSF2은 글래스 피시 3.0.1에서 실행] EJB3.1 @Asynchronous를 사용하는 경우에서 ConcurrentModificationExceptions을 방지하는 방법

는 난에 대한 몇 가지 기사를 읽고 EJB3.1의 새로운 @Asynchronous 메소드들 중 어느 것도 비동기 메소드의 위험성과 당신이 정말로 신경 써야 할 것들을 언급하지 않았다.

내 앱에서 많은 양의 메일을 보내는 @Asynchronous 전자 메일 서비스가 있습니다. CDI/Weld Bean에서이 서비스를 호출합니다. 테스트 도중, 나는 종종 ConcurrentModificationExceptions를 경험했지만, 지금까지는 때로는 충돌하는 곳과 이유를 이해하지 못했습니다.

그냥 내 콩 대략 중요한 부분, 같이 방법을 보여줍니다 : 내 CDI-콩에서

@Stateful @LocalBean 
public class EmailEJB { 
    //... Injections 

    @Asynchronous 
    public Future<Integer> sendEmails(User user, Message message) { 
    // ... send mails 
    return new AsyncResult<Integer>(1); 
    } 
} 

을, 나는이 같은이 EJB를 사용하고 있습니다 (JSF2에 노출 진행) :

@Named @SessionScoped 
public class MessageManager { 
    @EJB 
    public EmailEJB emailEJB; 

    public FutureEJB<Integer> progress; 

    public Integer getProgress() { 
    if (progress == null) return 0; 
    else { 
     return progress.get(); 
    } 
    } 

    public String sendMessage() { 
    (...) 
    progress = emailEJB.sendEmails(user, message); 
    (...) 
    } 
} 

나는 단지 일반적으로 다음과 같이 묻고 싶다. 내가 여기서 완전히 잘못된 것을하고 있는가? (스코프, 주사, 미래 사용)? ConcurrentModificationExceptions를 피하기 위해 @Asynchronous 메서드를 사용할 때 무엇을 신경 써야합니까?

나는 이메일을 EJB로 주입하고있다. EmailEJB 전체를 비동기로 만들고 @Inject @Asynchronous로 주입하는 것이 더 좋을까요? 차이점은 무엇입니까?

어떤 힌트를 환영합니다!

답변

0

가장 큰 실패는 내 CDI 빈에 세션 범위를 사용하는 것이 었습니다. 이것은 한 번에 비동기 EJB의 단 하나의 인스턴스 만 허용합니다. 즉, ConcurrentModificationException을 발생시킬 수 있습니다. (필자는 Future 값을 다시 할당하는 시점에서 생각합니다.)

그래서 @Asynchronous 메서드/클래스는 ConversationScope의 이상적인 후보인 것 같습니다. 이에 따라 CDI 빈을 변경했습니다. 예외는 없습니다.

2

비동기 메서드의 사용법은 좋았을 것입니다. 그러나 실제로 당신이 @Stateful이되기를 바랄 지 모르겠습니다. @Stateful bean이 @Asynchronous 메소드가 호출 될 때 다른 스레드에서 수정되거나 반복되는 것과 같은 소리가납니다. @Stateful bean이 List 필드를 말하고 그 목록에 대한 참조가 @Stateful bean 외부로 전달되어 사용되는 경우 이러한 일이 발생할 수 있습니다. 호출자 스레드와 비동기 스레드가 모두 목록을 사용한 경우, 일종의 동시 목록으로 변경하지 않으면 매우 나쁜 것입니다.

@Stateful 빈에서 state를 사용하는 경우 최종 (불변) 필드가있는 값 객체로 추출한 다음 @Asynchronous @Singleton 메소드 (@Lock (READ) 비동기 메서드가 @Singleton의 상태를 업데이트하지 않으면.

관련 문제