Hello and welcome Avinash!
There is a lot of ambiguity about the term “transaction”.
If you are looking for the equivalent of a “Two-phase commit” in an asynchronous distributed environment then I’m afraid there is nothing like that. That is, there is no automatic roll-back. In fact, in Axon (and event-driven systems in general) there is no roll-back at all. If something has already happened you can not “un-happen” it
What you can do instead is try to compensate for the effect(s) that the event has produced. What exactly that means depends on the domain. No framework can provide an automated generic solution.
Typically when there are multiple tasks that need to run in all-or-nothing fashion, one of the two approaches works:
The tasks are not conceptually different. It may appear they are from a UI perspective, given narrative, etc but in reality, it’s just one task consisting of many steps (that sometimes can be done independently or in random order). In such a case, the task should be modeled as operation on an
Agregate. Aggregates have consistency boundaries and do not update their state until all invariants are checked.
The tasks are conceptually different and their execution needs to be orchestrated in a specific way (enforce order, wait for some/all, execute conditionally, …). In such a scenario, you can use Saga. That will give you the option to define and control the process. It will NOT automatically fix failures though. As you design the process you’ll have to think about what can go wrong where and what compensating operations need to be executed in such cases.
I hope this helps.