[Моя настройка: приложение Java EE 6, с EJB3.1, CDI / Weld, JSF2, работающим на Glassfish 3.0.1]
Я прочитал несколько статей о новых методах @Asynchronous в EJB3.1, но ни один из них не упомянул об опасностях асинхронных методов и о том, что вам действительно нужно беспокоиться.
В моем приложении у меня есть служба @Asynchronous E-Mail, отправляющая много писем. Я вызываю эту услугу из CDI / Weld Bean. Во время моих тестов я часто сталкивался с исключениями ConcurrentModificationExceptions, но до сих пор я не совсем понимаю, где и почему иногда происходит сбой.
Просто чтобы показать, как примерно выглядят мои Бобы, важные части:
@Stateful @LocalBean
public class EmailEJB {
//... Injections
@Asynchronous
public Future<Integer> sendEmails(User user, Message message) {
// ... send mails
return new AsyncResult<Integer>(1);
}
}
В моем CDI-бине я использую этот 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);
(...)
}
}
Я просто хотел спросить в целом: делаю ли я здесь что-то совершенно не так (объемы, инъекции, использование Future)? О чем мне нужно заботиться при использовании @Asynchronous методов, чтобы избежать ConcurrentModificationExceptions?
Я внедряю письмо как EJB. Будет ли лучше сделать весь EmailEJB асинхронным и внедрить его с помощью @Inject @Asynchronous? Какая будет разница?
Любые советы приветствуются!