Very reasonable scenario Beka. In essence, this could still occur.
However, the chances are greatly minimized with what @Yvonne_Ceelie has shared in her blog post.
Now, towards your exact questions.
- When using the
SubscribingEventProcessorthe same thread used to invoke the command handler is used to invoke the event processor’s event handlers. Internally, this means the sameUnitOfWorkis indeed used. Thus if storing the field in the set (for validation) fails exceptionally, that would roll back the entireUnitOfWork. Doing so thus also roles back storing the event in the event store. - This depends on how you have set up the storage solution for your events and the set, to be honest. You could in essence regard the event store as the consistency solution for your Command Model (if you are event sourcing, that is). From that perspective, it wouldn’t be overly wrong to include the consistency-set to the same storage solution. However, as Axon Server users this wouldn’t be possible at all, since Axon Server is only an Event Store. Hence you would be left with two distinct storage solutions. If the consistency-set is actually stored in a database is a different choice of course. Maybe in-memory would be just fine, albeit that this approach requires a warm-up whenever you shut down your system.
You could adjust the process even further (for which we’re thinking about a blog-update actually). Think of having an interceptor which “locks” an entry for being used by other threads on the set. Then a TrackingEventProcessor would come after your command process (in thus a different UnitOfWork) which “sets in stone” that the field/id/email is really used. There are likely still some caveats in this approach I haven’t thought off (as I am still trying to figure out a fool proof approach).
At any note, I think it is good to deduce what level of consistency you really need in your application. going the full 100% automation (for anything really) is in most scenarios extremely tasking with any approach. Resolving about 80 to 90% could just be enough, with a manual approach (thus dedicated commands/events to revert the wrongfully used ID) next to it to resolve the problem when/if it occurs.