I am trying to persist an item in DB using a service and firing a JMS message for the subsequent service to pick up the persisted item so that it can process the same. This particular operations happens in a single transaction. But due to race condition at times, the second service is not able to fetch the respective item as its not yet persisted.
My use case is very common and there are some many discussion related to this in various forums. One solution for this issue is to use CDI events. I tried the same and could solve a part of the problem. The pseudo code is as follows:
@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
}
My only issue is when the persistence is successful & event is fired and just before the observer starts processing the event if the Jboss server goes down, the second service will not be notified as the JMS message wont be send.
Will the CDI container can internally handle this scenario so that the event will always be invoked? Will the observer be notified on server start automatically? If not, How do I handle this scenario so that my approach is fool proof?
NOTE: I have already tried out the retry approach in second service till the message is available. Also persisting the event in an other queue is an alternate approach which seems very tedious. Looking for a smart approach.
UPDATE: My initial code was written in such a way that the persistence and messaging was in single transaction. But that resulted in message consumption by second service before even first service persistence is successful resulting in error as second service could not find the required data which is yet to be persisted.
UPDATE 2: Intial approach pseudo code as follows:
@TransactionAttribute(TransactionAttributeType.REQUIRED)
public void processMessage() {
// code to persist data to DB
// code to publish JMS message to the consumer
}
Even by using xa-datasouce and xa-connection factory, the issue still exists.