Send multiple commands but create only events if they are all successfull

Hi,

I want so send several commands in forEach like:

commands.forEach(command -> {
try {
commandGateway.send(command);
} catch (Exception e) {
LOG.error(“Could not decrease amount”, e);
}
});

I have a check in the command handler and it thows an exception if an use case does not fulfilled the requirements,
So that can happen in one the commnands, therefore the others commands should not be executed, the events should not be applied.
I don’t want to rollback the events or something, it is possible to create only the events, if the complete list does not throw an exception?

How I solve this? Does Axon provide something for this use?

Hello,

You could consider using commandGateway.sendAndWait(command):

Sends the given {@code command} and wait for it to execute. The result of the execution is returned when available. This method will block indefinitely, until a result is available, or until the Thread is interrupted. When the thread is interrupted, this method returns {@code null}. If command execution resulted in an exception, it is wrapped in a {@link CommandExecutionException}.

nb: Your commands are executed synchronously but that does not mean you can rely on your views to be up to date.
That is, you can’t read from your views after forEach without some extra work.

Hi Arkadius,

Did you come across any solution for this ? Even I am looking for something like this.

My controller gets post request for list of objects/commands and I can only accept that post request if all the commands in list are valid. Which means I need a way to sendAndWait for all commands at once.

The handling of a Command is the transaction boundary within Axon. So there is no way to handle multiple commands within the same transaction.

The only exception to this rule is the SimpleCommandBus, which executes Commands in the thread that dispatched them. If the dispatching thread has an active transaction attached to it, it will execute it in that transaction as well. I wouldn’t recommend relying on it, though.

Instead, embrace eventual consistency. Try to fix problems when they occur, rather than attempting to run everything in an atomic transaction.
If that’s not possible, create a command handler that does all the operations in a single handler, instead of relying on a transaction to span multiple commands.

Hope this makes sense.
Cheers,

1 Like