is there any sample for handling twice event processing on readside ?
I’m not really sure what you mean. Why would you want to handle an event twice?
like option 2…
Hi Meong Meong,
I assume that term “message” from the article corresponds to Command concept in Axon/CQRS (simply because Events, as another type of messages, must be free of duplication conceptually).
The article mentions two types of Command processing (I unified examples):
(A) “Naturally idempotent”
Balance = amount;
(B) “Naturally non-idempotent”
Balance += amount;
So, the focus is only on the B-type non-idempotent for Command processing which requires some extra handling to introduce “artificial idempotence”.
The two approaches to introducing this artificial idempotence are essentially the same (checking against a store/buffer with message ids/hashes of previously processed messages).
The only difference between the two options is the place where this deduplicator is implemented (mapped into Axon terms):
(1) aggregate command handler
(2) (guessing) command interceptor
I haven’t approached this problem practically yet.
I only guess that (2) command interceptor is more natural place than (1) aggregate command handler because deduplication is some form of command validation.
Take a look at section “3.5. Command Interceptors”:
I must correct my previous post - the example of “naturally idempotent” command is wrong (or not clarified enough).
Just think about another command instance between these two duplicated ones.
Balance = amount1; // original
Balance = amount2; // another non-duplicate command of the same type
Balance = amount1; // duplicate
Is this really “naturally idempotent” command type? No.
In fact, even the original example from the article is also non-idempotent in the latter “Truly Idempotent” sense (see next).
Think about duplicate command “switch on the light” (e.g. received minutes after original) which overwrites currently required “light is off” state set by other commands in between.
Partially Idempotent versus Truly Indepotent
Well, maybe there are some mathematical terms which distinguish idempotence between:
- “Partially Idempotent”: the result is the same only with original command instance and any number of its duplicates (nothing in between).
- “Truly Idempotent”: the result is the same with any command instances in any order with any number of duplicates.
The “natural idempotent” example before is clearly not idempotent in the latter “Truly Idempotent” sense as it will overwrite any state changed between original and duplicate.
The easiest safeguard against handling the same command twice is by attaching the command’s message identifier as metadata to events that result from this command.
Each time the aggregate receives a command it can check if it is one of the command messages it has already processed. This is easy to do if you’re using event sourcing as all you need to do is add a collection of the last, say, 100 commands and make sure the incoming command’s id is not in the collection. No separate store required!
Right now Axon does not do this for you out of the box. However, it is very easy to implement yourself.
Are you able to confirm if Axon has changed since you last posted this message?
I’m in a scenario where I want to prevent someone from posting duplicate applications;
An application is created and a new stream ID is generated.
In the future, 2 duplicate applications are then received to update the record for this stream ID.
I need to prevent the duplicate application from triggering an event.
Grateful for any advice on this scenario.
Set validation, as this is called, has to be approached somewhat differently when using Event Sourcing. The issue itself has nothing to do with Axon. If you use the GenericJpaRepository, this is easy to do.
With Event Sourcing, you don’t have a table with ‘current state’ to validate uniqueness.
The framework doesn’t provide support for this out of the box. We had an issue on our backlog, but we decided (based on community feedback) not to implement it. It is better to make the choice for performing set validation explicit.
There are a few options.
- embrace eventual consitency in your system. Let the duplicates occur and fix them once you find them.
- use the reservation pattern. Express your intent first, and have a component validate that. Usually a bit overkill for simple set validation, but useful when the checks become more complex)
- create a shared set (e.g. a database table with unique constraints) where you add items before executing the command. This basically creates a mini state-stored component to allow uniqueness constraints.
Hope this helps.