How Transactions Work
Overview
At an abstract level, a transaction is a formal exchange between computer systems. The formality in it implies that there is an expectation of “success” which is defined in pre-agreed terms. The most typical transaction scenarios are as follows:
- Communication transaction: the guarantee of message/data arrival with disregard to any potential side-effects.
- State-modifying transaction: a series of guarantees concerning the entities targeted for modification. Those embodied by the concept of ACID transaction are the most typical.
Communication Transaction
A communication transaction boils down to guarantees of dispatch and arrival:
Guarantee of dispatch
This is the confirmation that the message has left the intended system boundary and is heading towards its destination. Most default asynchronous One-Way MEP consumer-side stacks have an internal queue; thus, when a message is “sent” it does not mean that it has left the consumer’s system boundary. This means that a troubleshooting process looking into “why a message has not arrived” may involve looking both at the provider-side and consumer-side queues.
Guarantee of arrival
This is the confirmation that the intended provider has received the message. All MEPs offer the possibility of verifying arrival except for the strict Asynchronous One-Way MEP. Such a possibility does not imply that arrival verification is automatic—it must be implemented.
State-modifying Transaction
A state-modifying transaction is one that may potentially change the state of one or more entities. In turn, in a distributed environment, such a state change may be triggered by means of a communication transaction, and each entity may be encapsulated by one or more services.
ACID Transaction
An ACID Transaction in the context of a service invocation has the following properties:
- Atomic: the transaction is either successful or produces no effect.
- Consistent: following an invocation, the service and its dependent back-ends are left in a consistent state regardless of the transaction’s outcome.
- Isolated: the service’s state, as well as that of its dependent back-ends, is not influenced by other concurrent service invocations.
- Durable: after an invocation succeeds, it is guaranteed that the effect is persistent. No system failure is able to undo the result of the service call by accident.
Two-Phase Commit (2PC)
This is a transactional mechanism used when data storage can be safely coordinated by a software system.
In a distributed system, implementing a genuine 2PC system is more difficult than in the RDBMS world because the state-modifying participants may unexpectedly become unavailable during a transaction, leaving the transaction provider in a non-final state for an undefined period of time. The WS-Atomic Transaction specification attempts to cover this scenario, although it could be argued that it rather provides a compensation protocol.
This is an oversimplified summary of the life-cycle states applicable to the transaction provider implementing the 2PC protocol, barring the event of the provider and back-ends becoming unavailable:
State | Next States | Description |
---|---|---|
Ready | Preparing | Waiting to get active. |
Preparing | Aborting, Committing | Asking back-ends to prepare—abort if one or more back-ends aren’t ready. |
Aborting | Ready | Asking back-ends to release resources. |
Committing | Rolling-back, Ready | Asking back-ends to commit changes—roll back if one or more back ends cannot commit. |
Rolling back | Ready | Asking back-ends to reverse changes. |
Compensation
Compensation is a loose transactional mechanism that relies on setting former values on back-end systems as opposed to executing a rollback as is the case in in the RDBMS 2PC protocol. Compensation is, in reality, the only feasible way to try to emulate ACID properties in a distributed environment since a straight-forward rollback—as intended in the RDBMS world—cannot be applied to heterogeneous systems in a systematic fashion.