Skip to content

shrirambalakrishnan/two-phase-commit

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

15 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Two-Phase Commit - Food Ordering System

A Go microservices project demonstrating the two-phase commit (2PC) protocol for distributed transaction coordination across three services, each with its own PostgreSQL database.

Services

Service Port Database Role
Order Service 8081 orderdb Coordinator — orchestrates the 2PC protocol
Delivery Service 8082 deliverydb Manages delivery agents (reserve/assign)
Store Service 8083 storedb Manages food packets (reserve/assign)

How the Two-Phase Commit Works

When a user creates an order (POST /orders/create):

Phase 1 — Reserve (Prepare/Vote)

  1. Insert order with PENDING status
  2. POST /foods/reserve — Store Service locks an available food packet (is_reserved = true)
  3. POST /agents/reserve — Delivery Service locks an available delivery agent (is_reserved = true)

Phase 2 — Assign (Commit)

  1. POST /foods/assign — Store Service assigns the reserved packet to the order (order_id = X)
  2. POST /agents/assign — Delivery Service assigns the reserved agent to the order (order_id = X)
User POST /orders/create {user_id: 1, food_id: 1}
        │
        ├─ Insert into orders (status = PENDING)
        │
        ├─ PHASE 1: PREPARE
        │   ├─ POST /foods/reserve
        │   │   └─ Store locks packet, sets is_reserved=true
        │   └─ POST /agents/reserve
        │       └─ Delivery locks agent, sets is_reserved=true
        │
        ├─ All Phase 1 responses successful?
        │   ├─ NO  → Return error (automatic transaction rollback)
        │   └─ YES → Proceed to Phase 2
        │
        ├─ PHASE 2: COMMIT
        │   ├─ POST /foods/assign
        │   │   └─ Store sets packet.order_id = orderID
        │   └─ POST /agents/assign
        │       └─ Delivery sets delivery.order_id = orderID
        │
        └─ Return order_id to user

Concurrency Control (Preventing double-booking)

  • Each service uses SELECT ... FOR UPDATE row-level locks within database transactions to prevent race conditions.
  • This ensures that when two concurrent requests try to reserve the same resource, one blocks until the other completes.

Known Limitations

  • The current implementation lacks explicit rollback/abort calls.
  • If a Phase 2 operation fails (e.g., food assign succeeds but delivery assign fails), there is no compensation logic to undo the partial commit.

About

2 Phase Commit implementation

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages