0

[私の設定: Java EE 6 アプリケーション、EJB3.1、CDI/Weld、Glassfish 3.0.1 で動作する JSF2 を使用]

EJB3.1 の新しい @Asynchronous メソッドに関する記事をいくつか読みましたが、非同期メソッドの危険性や、実際に注意する必要があることについて言及した記事はありませんでした。

私のアプリでは、@Asynchronous E-Mail サービスを使用して、大量のメールを送信しています。このサービスを CDI/Weld Bean から呼び出しています。テスト中に ConcurrentModificationExceptions が頻繁に発生しましたが、今までのところ、クラッシュする場所と理由がよくわかりません。

私の Beans が大まかにどのように見えるかを示すために、重要な部分は次のとおりです。

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

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

私のCDI-Beanでは、この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 全体を Asynchronous にして @Inject @Asynchronous で注入したほうがよいでしょうか? 違いは何ですか?

どんなヒントでも大歓迎です!

4

2 に答える 2

2

非同期メソッドの使用は問題ないはずですが、本当に @Stateful にしたいのだろうかと思います。@Asynchronous メソッドが呼び出されているときに、@Stateful Bean 内の状態が別のスレッドで変更 (または反復) されているように聞こえます。これは、@Stateful Bean に List フィールドがあり、そのリストへの参照が @Stateful Bean の外に渡されて使用される場合に発生する可能性があります。呼び出し元スレッドと非同期スレッドの両方がリストを使用した場合、リストを何らかの並行リストに変更しない限り、非常に悪いことになります。

@Stateful Bean に状態がある場合は、それを final (不変) フィールドを持つ値オブジェクトに抽出し、それを @Asynchronous @Singleton メソッドに渡す方がよい場合があります。 async メソッドは @Singleton の状態を更新しません。

于 2010-08-03T21:32:25.440 に答える
0

私の最大の失敗は、CDI Bean に Session Scope を使用したことです。これにより、一度に 1 つの非同期 EJB のインスタンスのみが許可されます - おそらく ConcurrentModificationException が発生します (Future 値を再割り当てする時点であると思います)。

したがって、@Asynchronous メソッド/クラスは、ConversationScope の理想的な候補のようです。それに応じてCDI Beanを変更しました。これまでのところ例外はありません。

于 2010-08-02T22:43:35.920 に答える