A sequence of contingent business activities might take hours, days or weeks or even longer to complete. It sometimes corresponds to what is called a long running transaction or saga in the software industry.
Distributed transactions aren't suitable for long running contingent business activities, it is not reasonable to lock resources like bank accounts for weeks.
The contingent nature of business activities must be properly modelled by business software and that means there's a need for compensating transactions. This is inevitable. For example, a buyer may get a refund when a received good is defective, or a a buyer may have the right to cancel a contract within a a cooling off period.
Consider the case of a buyer that purchases goods from a seller. This starts from when the buyer first raises a purchase order (PO) through to when they receive the goods.
The buyer may check that the goods are currently in stock. This is only suggestive information, there is no guarantee that they will be in stock when the order is placed.
The following shows how some contingent business activities can be modelled:
This is a very direct and straightforward modelling of the contingent business activities, and everywhere involves double entry book-keeping.
It's all about the data in the databases and avoiding notions of distributed consistency constraints. Who owns what money/stock is recorded in databases and only in databases.
It has nothing to do with the state of the transient messaging system, such as what messages are queued to be sent, or are in flight or have been received. The messages are transient and therefore play second fiddle to the data-centric point of view.
This is a different point of view to most of the software industry, which is fixated on "service oriented" and "message oriented" architectures - i.e. state machines and messages, when the emphasis should really be on modelling the state of contingent business activities with pure data in databases.
More specifically the software industry is fixated on hideous approaches involving anti-patterns like 2PC, at least once delivery, persistent messages, duplicate message testing, idempotent message handling, retry loops, message replay, timeouts, dead letter queues [] etc.