Я пытаюсь сохранить элемент в БД, используя службу, и запускаю сообщение JMS для последующей службы, чтобы забрать сохраненный элемент, чтобы он мог обработать его.Эта конкретная операция происходит в одной транзакции.Но из-за состояния гонки время от времени вторая служба не может получить соответствующий элемент, поскольку он еще не сохранен.
Мой вариант использования очень распространен, и на разных форумах обсуждается множество вопросов, связанных с этим.Одним из решений этой проблемы является использование событий CDI.Я попробовал то же самое и мог решить часть проблемы.Псевдокод выглядит следующим образом:
@Inject
@Transaction
private Event<Item> itemEvent;
public void handleItem(Item item) {
//code to persist the item
itemEvent.fire(item);
}
@Asynchronous
public void observeAfterTransactionCompletion(@Observes(during = TransactionPhase.AFTER_SUCCESS) @Transaction Item item) {
//code to send JMS message to the second service
}
Моя единственная проблема - когда персистентность успешна и событие запускается, и непосредственно перед тем, как наблюдатель начинает обрабатывать событие, если сервер Jboss выходит из строя, вторая служба не будетполучать уведомление, поскольку сообщение JMS не будет отправлено.
Может ли контейнер CDI внутренне обработать этот сценарий, чтобы событие всегда вызывалось?Будет ли наблюдатель уведомлен о запуске сервера автоматически?Если нет, то как мне справиться с этим сценарием, чтобы мой подход был надежным?
ПРИМЕЧАНИЕ: Я уже опробовал подход повторной попытки во втором сервисе, пока сообщение не станет доступным.Также сохранение события в другой очереди - альтернативный подход, который кажется очень утомительным.В поисках разумного подхода.
ОБНОВЛЕНИЕ: Мой исходный код был написан таким образом, что постоянство и обмен сообщениями были в одной транзакции.Но это привело к потреблению сообщений второй службой до того, как даже первое сохранение службы было успешным, что привело к ошибке, поскольку вторая служба не смогла найти требуемые данные, которые еще должны быть сохранены.
ОБНОВЛЕНИЕ 2: Псевдокод первоначального подхода выглядит следующим образом: @TransactionAttribute(TransactionAttributeType.REQUIRED)
public void processMessage() {
// code to persist data to DB
// code to publish JMS message to the consumer
}
Даже при использовании xa-datasouce и фабрики xa-connection проблема все еще существует.