Distributed Transactions in Microservices: Why 2PC Doesn’t Fit and How Sagas Help

This is the first article in a series that walks through a simple order solution for a hypothetical company called “Simply Order”. The company expects high traffic and needs to design a resilient, scalable, and distributed Order system.

We’ll go step …


This content originally appeared on DEV Community and was authored by Mohamed Hassan

This is the first article in a series that walks through a simple order solution for a hypothetical company called “Simply Order”. The company expects high traffic and needs to design a resilient, scalable, and distributed Order system.

We’ll go step by step, building the system and discussing the challenges along the way, while exploring the trade-offs between possible solutions.

In this first article, we’ll describe the problem and review different approaches — with their pros and cons — before choosing our recommended path. In the upcoming articles, we’ll implement the solution, share code examples, and highlight best practices.

The Problem

The company chose a microservice architecture to build their system. They started with an Order microservice, but soon realized it was becoming a bottleneck.

This service has to handle multiple responsibilities:
Accept orders and store them.

  • Communicate with the Inventory Service to check product availability.
  • Communicate with the Payment Service to authenticate and process user payments.
  • Communicate with the Fulfillment Service to start shipping and logistics.
  • Finally, notify users and other interested participants through different channels — e.g., messages, emails, and so on.

These multiple operations should be consistent and ideally treated as a single unit of work. But here’s the problem:

  • Each microservice has its own DB → can’t use a single DB transaction across them.
  • One service may commit successfully, while others fail. This means one service may commit successfully, while others fail.
  • Some services may even use NoSQL databases, which don’t support traditional transactions at all.
  • And to make it worse, some microservices might be unreachable at the time of the operation.
  • So the big question is: how do we manage these operations and keep the system consistent in the chaotic world of microservices?

Solutions

Two-Phase Commit (2PC)

A straightforward solution that often comes to mind is Two-Phase Commit (2PC).

Some relational databases and drivers support it, making it possible to coordinate a distributed transaction.

Here’s how it works:

  1. A coordinator talks to the participants (other microservices or their databases) and asks them to prepare their transaction.
  2. If all participants reply with yes (prepared), the coordinator sends a commit message to everyone.
  3. If one or more reply with no (or fail to respond), the coordinator sends a rollback message to all participants.

Two-Phase Commit Sequence Diagram

Pros & Cons

Pros
  • Guarantees atomicity across multiple services.
  • Conceptually simple — feels like a “distributed version” of a database transaction.
Cons
  • Blocking: the prepare phase locks database resources until the final commit/rollback, which hurts scalability. Also, if any participant is down or unresponsive, the whole transaction may block and hold locks.
  • Single point of failure: if the coordinator crashes, participants may stay locked indefinitely.
  • Limited Support: Not all databases or drivers support XA/2PC transactions (especially many NoSQL or cloud-native DBs).

Because of these limitations, 2PC is generally not suitable for microservices in a cloud-native environment.

Saga

Saga splits one big transaction that involves multiple services into a sequence of local transactions owned by each service. If one service fails to commit its transaction, other services get informed about that failure, and instead of rollback (services do not block, they already committed their changes), they perform a compensating transaction. i.e. if the Inventory service deducted/reserved certain items, it will create another transaction to add/free the deducted items.

But how can each service be informed about other services?

There are 2 types of Saga: Choreography and Orchestration

There are 2 types of Saga: Choreography and Orchestration

Choreography (event-driven)

Services emit domain events, i.e. OrderCreated, InventoryReserved, PaymentFailed, etc. Other interested services subscribe to these events and can create a compensating transaction if needed. i.e. when a PaymentFailed event is published, the Inventory service creates a compensating transaction to free reserved items, the Order service updates its order status to failed, and so on.

Choreography Saga

Pros
  • Natural for event-driven systems.
  • Simple to start and each service is decoupled.
Cons
  • Harder to manage complex flows, timeouts, and branching.
  • Risk of spaghetti events: imagine if just 5 services are involved, and each service could listen to the others!

Orchestration (command-driven)

A central orchestrator sends commands to other services and waits/listens for results in a non-blocking manner.
The workflow is explicit code from domain logic, centralized to manage retries, timeouts, compensations, etc.

Orchestration Saga

Pros
  • One source of truth, i.e. single place for flow, retries, and timeouts.
  • Clear visibility even with complex processes.
Cons
  • The orchestrator could be a single point of failure, so it is a critical component.
  • Slightly tighter coupling with the orchestrator API, as typically it is a 3rd-party library/component.

Saga in both modes shares some common pros and cons.

Pros

  • Saga fits microservices naturally as each microservice is loosely coupled from the others.
  • Saga is non-blocking by the nature of its communication, which is critical for the scalability of microservices.

Cons

  • Eventual consistency: the system is temporarily inconsistent until all steps (or compensations) finish.
  • Complex compensation logic: “undoing” business actions is not always straightforward.
  • Increased complexity: i.e. handling idempotency and compensating logic.

Wrapping up

In this article, we looked at the problem of distributed transactions, why 2PC is not suitable for microservices, and how the Saga pattern (choreography and orchestration) helps solve it.

In the next article, we’ll start implementing the solution using Temporal as an orchestrator-based Saga. We’ll walk through code examples and best practices step by step.

👉 Follow this series if you’re interested in building resilient microservices, and feel free to share your thoughts or questions in the comments — I’d love to hear your perspective.


This content originally appeared on DEV Community and was authored by Mohamed Hassan


Print Share Comment Cite Upload Translate Updates
APA

Mohamed Hassan | Sciencx (2025-08-27T18:40:25+00:00) Distributed Transactions in Microservices: Why 2PC Doesn’t Fit and How Sagas Help. Retrieved from https://www.scien.cx/2025/08/27/distributed-transactions-in-microservices-why-2pc-doesnt-fit-and-how-sagas-help-3/

MLA
" » Distributed Transactions in Microservices: Why 2PC Doesn’t Fit and How Sagas Help." Mohamed Hassan | Sciencx - Wednesday August 27, 2025, https://www.scien.cx/2025/08/27/distributed-transactions-in-microservices-why-2pc-doesnt-fit-and-how-sagas-help-3/
HARVARD
Mohamed Hassan | Sciencx Wednesday August 27, 2025 » Distributed Transactions in Microservices: Why 2PC Doesn’t Fit and How Sagas Help., viewed ,<https://www.scien.cx/2025/08/27/distributed-transactions-in-microservices-why-2pc-doesnt-fit-and-how-sagas-help-3/>
VANCOUVER
Mohamed Hassan | Sciencx - » Distributed Transactions in Microservices: Why 2PC Doesn’t Fit and How Sagas Help. [Internet]. [Accessed ]. Available from: https://www.scien.cx/2025/08/27/distributed-transactions-in-microservices-why-2pc-doesnt-fit-and-how-sagas-help-3/
CHICAGO
" » Distributed Transactions in Microservices: Why 2PC Doesn’t Fit and How Sagas Help." Mohamed Hassan | Sciencx - Accessed . https://www.scien.cx/2025/08/27/distributed-transactions-in-microservices-why-2pc-doesnt-fit-and-how-sagas-help-3/
IEEE
" » Distributed Transactions in Microservices: Why 2PC Doesn’t Fit and How Sagas Help." Mohamed Hassan | Sciencx [Online]. Available: https://www.scien.cx/2025/08/27/distributed-transactions-in-microservices-why-2pc-doesnt-fit-and-how-sagas-help-3/. [Accessed: ]
rf:citation
» Distributed Transactions in Microservices: Why 2PC Doesn’t Fit and How Sagas Help | Mohamed Hassan | Sciencx | https://www.scien.cx/2025/08/27/distributed-transactions-in-microservices-why-2pc-doesnt-fit-and-how-sagas-help-3/ |

Please log in to upload a file.




There are no updates yet.
Click the Upload button above to add an update.

You must be logged in to translate posts. Please log in or register.