Short answer
The 2PC protocol enforces synchronous distributed locking through a central coordinator to guarantee strong consistency, but it is slow and has a single point of failure. Saga manages the transaction as a sequence of separate local transactions, with compensating transactions to roll back if something fails.
Explanation
In Saga, each service runs its local transaction and emits an event telling the next service to continue. If a middle step fails (for example, a credit card is declined by the payment service after a seat was reserved by the ticket service), it emits a failure event and starts the rollback plan by running compensating transactions in reverse (canceling the seat reservation). Saga can use Choreography, where services communicate through events, or Orchestration, where a central coordinator directs commands and compensations.
Code example
def place_order(order):
done = []
steps = [
(create_order, cancel_order),
(reserve_inventory, release_inventory),
(charge_card, refund_card),
]
try:
for action, compensate in steps:
action(order) # each step is a LOCAL transaction in its own service
done.append(compensate)
except Exception:
for compensate in reversed(done): # compensating transactions run newest first
compensate(order)
mark_order_failed(order)
raiseCommon mistakes
- Using Two-Phase Commit (2PC) in large cloud service environments, causing severe delays and resource locks during any network disruption.