jakarta-eeevent-handlingrace-conditionmessage-driven-bean

Race condition on MDB: which is the best way to handle it?


I have an event-driven application based on MDB, spring integration and JPA for persistence. The application is deployed on weblogic 10.3 with a max-pool-size default value (16).

My application need to handle some messages that modfies DB. Imagine that I have use case where I have to handle some messages that for their logic need to insert a domain object if it does not exist or update it if it exists.

So my component that modifes the DB check if the object exists or not and then call the merge on JPA. Since two concurrent messages are executed in parallel when I call the merge on dao, JPA triggers two insert statement since the object is not yet persisted and so only one of them is correctly executed.

Is there a pattern to handle this kind of "race condition" in an event-driven application?

Kind regards Massimo


Solution

  • The simplest solution is to catch the exception thrown by the second insert, then call merge again, which should perform the update.

    Alternatively, you could try performing the merge in SERIALIZABLE transaction isolation, which should ensure that the second merge is blocked until the first one has completed, and the second one should then perform an update.

    The main problem with this whole scenario is that if you have multiple concurrent events coming in which entail modifying a given entity, then how do you ensure that you're executing them in the correct sequence? Surely you need to process these sequentially, rather than concurrently? If you use concurrent event consumers, the order is going to be non-deterministic.