Distributed Locking

In a single-machine system, you use a Mutex or Semaphore to prevent multiple threads from accessing the same resource at once.

But what if you have multiple servers?

A local lock won't work because different servers don't share memory.

This is where Distributed Locking comes in.


Why Distributed Locking is Required

Without it, you run into Race Conditions.

Example: Booking a Ticket

  1. User A checks if a seat is available on Server 1.
  2. User B checks the same seat on Server 2 at the exact same time.
  3. Both servers see the seat is free.
  4. Both servers book the same seat.

Result: Two people have the same ticket.


How It Works

A distributed lock needs a centralized source of truth that all servers can check.

The process:

  1. Server 1 asks the central store for a lock on "Seat_42".
  2. Central store grants the lock (usually with a timeout/TTL).
  3. Server 2 asks for the same lock.
  4. Central store says "No, Server 1 has it."
  5. Server 1 finishes booking and releases the lock.

Common Tools for Locking

1. Redis (Redlock)

2. ZooKeeper

3. Etcd


The "Fencing Token" Problem

What if Server 1 gets the lock, but then it pauses (due to Garbage Collection) for a long time?

Solution: Fencing Tokens

sequenceDiagram
    participant S1 as Server 1
    participant Lock as Lock Manager
    participant DB as Database
    
    S1->>Lock: Get Lock
    Lock-->>S1: Token: 33
    Note over S1: GC Pause (Long Delay)
    Note over Lock: Lock Expires
    participant S2 as Server 2
    S2->>Lock: Get Lock
    Lock-->>S2: Token: 34
    S2->>DB: Update (Token 34)
    DB-->>S2: OK
    
    S1->>DB: Update (Token 33)
    DB-->>S1: REJECT (34 is latest)

Key Takeaways

Only use distributed locks when you absolutely have to. They add latency and complexity.