Bird
Raised Fist0
Microservicessystem_design~7 mins

Two-phase commit (and why to avoid it) in Microservices - System Design Guide

Choose your learning style10 modes available

Start learning this pattern below

Jump into concepts and practice - no test required

or
Recommended
Test this pattern10 questions across easy, medium, and hard to know if this pattern is strong
Problem Statement
When multiple microservices need to update their own databases as part of one user action, a failure in any service can leave data inconsistent. Without coordination, partial updates cause data corruption, leading to user confusion and system errors.
Solution
Two-phase commit coordinates all involved services to agree on committing or aborting a transaction. First, a coordinator asks each service if it can commit (prepare phase). If all agree, the coordinator tells them to commit (commit phase). If any service cannot commit, all roll back to keep data consistent.
Architecture
Coordinator
Service A DB
Service B DB

This diagram shows the coordinator communicating with multiple service databases in two phases: prepare and commit, ensuring all-or-nothing updates.

Trade-offs
✓ Pros
Ensures strong consistency across multiple services by coordinating commits.
Prevents partial updates that cause data corruption.
Simple conceptually for small numbers of services.
✗ Cons
Blocks resources during the prepare phase, reducing system availability.
Single coordinator failure can halt progress, causing system stalls.
Does not scale well with many services due to increased latency and complexity.
Use when strict consistency is mandatory and the number of services involved is small (under 3-5), and the system can tolerate blocking during commit.
Avoid when system requires high availability, low latency, or involves many services; also avoid if coordinator failure cannot be quickly recovered.
Real World Examples
Amazon
Used two-phase commit in early order processing to ensure inventory and payment services updated atomically before moving to eventual consistency models.
Uber
Applied two-phase commit in limited cases for trip booking to ensure driver and rider data consistency before switching to compensation-based patterns.
LinkedIn
Used two-phase commit in legacy systems for profile updates spanning multiple databases before adopting event-driven eventual consistency.
Code Example
The before code shows independent updates that can fail partially. The after code introduces a coordinator that asks each service to prepare, then commits all or rolls back all, ensuring atomicity.
Microservices
### Before (no coordination, risk of partial failure)
class ServiceA:
    def update(self):
        # update local DB
        pass

class ServiceB:
    def update(self):
        # update local DB
        pass

# Caller calls both updates independently
service_a = ServiceA()
service_b = ServiceB()
service_a.update()
service_b.update()  # if this fails, data is inconsistent


### After (Two-phase commit coordinator)
class Coordinator:
    def __init__(self, services):
        self.services = services

    def two_phase_commit(self):
        # Phase 1: prepare
        for s in self.services:
            if not s.prepare():
                self.rollback_all()
                return False
        # Phase 2: commit
        for s in self.services:
            s.commit()
        return True

    def rollback_all(self):
        for s in self.services:
            s.rollback()

class ServiceA:
    def prepare(self):
        # check if update possible
        return True
    def commit(self):
        # apply update
        pass
    def rollback(self):
        # undo changes
        pass

class ServiceB:
    def prepare(self):
        return True
    def commit(self):
        pass
    def rollback(self):
        pass

services = [ServiceA(), ServiceB()]
coordinator = Coordinator(services)
coordinator.two_phase_commit()
OutputSuccess
Alternatives
Saga pattern
Breaks a transaction into a sequence of local transactions with compensating actions instead of a global lock.
Use when: Use when you need higher availability and scalability with eventual consistency.
Eventual consistency with event sourcing
Services update independently and communicate changes via events, accepting temporary inconsistencies.
Use when: Choose when system can tolerate temporary inconsistencies and requires high throughput.
Summary
Two-phase commit prevents partial updates by coordinating all services to commit or rollback together.
It ensures strong consistency but can block system progress and reduce availability.
Modern microservices often avoid it in favor of eventual consistency patterns like sagas.

Practice

(1/5)
1. What is the main purpose of the two-phase commit protocol in microservices?
easy
A. To automatically retry failed requests
B. To speed up communication between services
C. To allow services to work independently without coordination
D. To ensure all services agree on a transaction before committing

Solution

  1. Step 1: Understand the role of two-phase commit

    Two-phase commit is designed to make sure all parts of a distributed transaction agree to commit or abort together.
  2. Step 2: Identify the main goal in microservices

    Its main goal is to keep data consistent across multiple services by coordinating their commit decisions.
  3. Final Answer:

    To ensure all services agree on a transaction before committing -> Option D
  4. Quick Check:

    Two-phase commit = agreement before commit [OK]
Hint: Two-phase commit means all must say yes before commit [OK]
Common Mistakes:
  • Thinking it speeds up communication
  • Believing services act independently
  • Assuming it retries failed requests automatically
2. Which of the following correctly describes the two phases in the two-phase commit protocol?
easy
A. Abort phase where coordinator asks, Prepare phase where services finalize
B. Prepare phase where coordinator asks, Commit phase where services finalize
C. Commit phase where coordinator asks, Prepare phase where services finalize
D. Prepare phase where services finalize, Commit phase where coordinator asks

Solution

  1. Step 1: Recall the two phases names and order

    The first phase is the prepare phase where the coordinator asks all services if they can commit.
  2. Step 2: Understand the commit phase

    If all agree, the coordinator sends a commit command to finalize the transaction.
  3. Final Answer:

    Prepare phase where coordinator asks, Commit phase where services finalize -> Option B
  4. Quick Check:

    Prepare then commit = correct phase order [OK]
Hint: Prepare asks, commit finalizes transaction [OK]
Common Mistakes:
  • Mixing up the order of prepare and commit phases
  • Confusing abort with prepare phase
  • Thinking services finalize before coordinator asks
3. Consider a microservices system using two-phase commit. If one service fails to respond during the prepare phase, what is the expected outcome?
medium
A. The coordinator ignores the failure and proceeds
B. The coordinator commits the transaction anyway
C. The coordinator aborts the transaction and tells all services to rollback
D. The coordinator retries the prepare phase indefinitely

Solution

  1. Step 1: Analyze failure during prepare phase

    If any service fails to respond or votes no during prepare, the coordinator must abort to keep consistency.
  2. Step 2: Understand coordinator's action

    The coordinator sends abort commands to all services to rollback any partial changes.
  3. Final Answer:

    The coordinator aborts the transaction and tells all services to rollback -> Option C
  4. Quick Check:

    Failure in prepare = abort transaction [OK]
Hint: Any no or failure in prepare means abort [OK]
Common Mistakes:
  • Assuming commit happens despite failure
  • Thinking coordinator retries forever
  • Ignoring failure and proceeding anyway
4. A developer notices that their two-phase commit implementation causes long delays and system hangs when a service crashes. What is the most likely cause?
medium
A. The coordinator is waiting indefinitely for responses from crashed services
B. The services are committing too quickly without coordination
C. The coordinator is skipping the prepare phase
D. The services are not logging their transactions

Solution

  1. Step 1: Identify cause of delays and hangs

    In two-phase commit, the coordinator waits for all services to respond during prepare phase.
  2. Step 2: Understand impact of crashed services

    If a service crashes, the coordinator may wait indefinitely, causing delays and system hangs.
  3. Final Answer:

    The coordinator is waiting indefinitely for responses from crashed services -> Option A
  4. Quick Check:

    Waiting on crashed service = system hang [OK]
Hint: Coordinator waits forever if service crashes [OK]
Common Mistakes:
  • Thinking services commit too fast causes hangs
  • Believing skipping prepare phase causes delays
  • Assuming missing logs cause system hangs
5. Why is two-phase commit often avoided in modern microservices architectures despite ensuring consistency?
hard
A. Because it causes blocking, reduces availability, and hurts scalability
B. Because it does not guarantee data consistency
C. Because it requires no coordination between services
D. Because it is too simple and lacks fault tolerance

Solution

  1. Step 1: Understand drawbacks of two-phase commit

    Two-phase commit blocks resources while waiting, reducing system availability and scalability.
  2. Step 2: Recognize why modern systems avoid it

    Modern microservices prefer eventual consistency and non-blocking patterns to improve performance and fault tolerance.
  3. Final Answer:

    Because it causes blocking, reduces availability, and hurts scalability -> Option A
  4. Quick Check:

    Blocking and low availability = avoid two-phase commit [OK]
Hint: Two-phase commit blocks and limits scalability [OK]
Common Mistakes:
  • Thinking it does not guarantee consistency
  • Believing it requires no coordination
  • Assuming it is too simple