Full Stack • Java • System Design • Cloud • AI Engineering

Distributed Locks in Distributed Systems

Learn Distributed Locks from the ground up. Understand why distributed locks are required, how they work, pessimistic vs optimistic locking, Redis Redisson, ZooKeeper, etcd, Consul, database locks, leader election, Spring Boot implementation, and real-world examples from Banking, Amazon, Uber, Netflix, and Kubernetes.


Introduction

Imagine your e-commerce application is deployed across 10 Spring Boot instances.

Load Balancer

↓

10 Spring Boot Servers

↓

PostgreSQL

A product has only 1 item left in stock.

At exactly the same moment,

two customers click Buy Now.

Request A

Server 1

Request B

Server 8

Both servers read

Inventory = 1

Both update inventory.

Result

Inventory = -1

Overselling

This is one of the most common distributed system problems.

The solution is Distributed Locking.


Learning Objectives

After completing this article, you'll understand:

  • What is a Distributed Lock?
  • Why Distributed Locks?
  • Local Lock vs Distributed Lock
  • Lock Lifecycle
  • Mutual Exclusion
  • Redis Distributed Lock
  • Redisson
  • ZooKeeper Locks
  • etcd Locks
  • Consul Locks
  • Database Locks
  • Leader Election
  • Lock Expiration
  • Deadlock Prevention
  • Spring Boot Integration
  • Best Practices

What is a Distributed Lock?

A Distributed Lock ensures only one application instance can execute a critical section at a time.

Unlike Java synchronized blocks,

Distributed Locks work across multiple servers.


Local Lock

Java

synchronized(orderService){
    processOrder();
}

Works only

Inside One JVM

Distributed Lock

flowchart TD
    S1[Spring Boot Instance 1]

    S2[Spring Boot Instance 2]

    S3[Spring Boot Instance 3]

    LOCK[(Distributed Lock)]

    S1 --> LOCK
    S2 --> LOCK
    S3 --> LOCK

Only one instance owns the lock.


Why Local Locks Fail

flowchart TD
    JVM1[Server 1]

    JVM2[Server 2]

    JVM3[Server 3]

    JVM1 --> DB[(Database)]
    JVM2 --> DB
    JVM3 --> DB

Each JVM has its own memory.

A synchronized block on Server 1 has no effect on Server 2.


Why Distributed Locks?

Distributed locks solve

  • Double Payments
  • Duplicate Orders
  • Duplicate Batch Jobs
  • Inventory Overselling
  • Scheduler Conflicts
  • Leader Election
  • Configuration Updates

Real Banking Example

Customer Balance

$50,000

ATM

Withdraw $20,000

Mobile App

Withdraw $20,000

Without locking,

both transactions may succeed.


Lock Architecture

flowchart TD
    CLIENT[Clients]

    APP1[Spring Boot 1]

    APP2[Spring Boot 2]

    APP3[Spring Boot 3]

    REDIS[(Distributed Lock)]

    DB[(Database)]

    CLIENT --> APP1
    CLIENT --> APP2
    CLIENT --> APP3

    APP1 --> REDIS
    APP2 --> REDIS
    APP3 --> REDIS

    APP1 --> DB
    APP2 --> DB
    APP3 --> DB

Lock Lifecycle

flowchart TD
    START[Request Lock]

    ACQUIRE[Acquire Lock]

    PROCESS[Execute Business Logic]

    RELEASE[Release Lock]

    END[Next Request]

    START --> ACQUIRE
    ACQUIRE --> PROCESS
    PROCESS --> RELEASE
    RELEASE --> END

Request Flow

sequenceDiagram
    participant Client
    participant App
    participant Redis
    participant Database

    Client->>App: Buy Product

    App->>Redis: Acquire Lock

    Redis-->>App: Lock Granted

    App->>Database: Update Inventory

    Database-->>App: Success

    App->>Redis: Release Lock

    App-->>Client: Order Confirmed

Mutual Exclusion

Only one process enters the critical section.

flowchart TD
    LOCK[(Lock)]

    APP1[Instance 1]

    APP2[Instance 2]

    APP3[Instance 3]

    LOCK --> APP1

    APP2 -. Waiting .-> LOCK

    APP3 -. Waiting .-> LOCK

Lock States

Unlocked

↓

Acquire Lock

↓

Locked

↓

Business Logic

↓

Release Lock

↓

Unlocked

Lock Timeout

Suppose

Application crashes.

Without timeout,

the lock remains forever.

Solution

Lock TTL

30 Seconds

Automatically release stale locks.


Lock Timeout Diagram

flowchart TD
    LOCK[Acquire Lock]

    PROCESS[Processing]

    CRASH[Application Crash]

    TTL[TTL Expired]

    RELEASE[Auto Release]

    LOCK --> PROCESS
    PROCESS --> CRASH
    CRASH --> TTL
    TTL --> RELEASE

Redis Distributed Lock

Redis uses

SET key value NX PX 30000

Meaning

  • NX → Only if key doesn't exist
  • PX → Expiration Time

Redis Lock Flow

sequenceDiagram
    participant App1
    participant Redis
    participant App2

    App1->>Redis: SET Lock

    Redis-->>App1: OK

    App2->>Redis: SET Lock

    Redis-->>App2: Lock Exists

Redisson

Redisson provides

  • Distributed Lock
  • Fair Lock
  • Read Lock
  • Write Lock
  • Semaphore
  • CountDownLatch

Simple Java API

RLock lock = redisson.getLock("payment-lock");

lock.lock();

try{
   processPayment();
}
finally{
   lock.unlock();
}

ZooKeeper Lock

ZooKeeper creates

Ephemeral Sequential Nodes

Smallest sequence number owns the lock.

flowchart TD
    CLIENTS[Clients]

    ZK[(ZooKeeper)]

    LOCK[Lock Owner]

    CLIENTS --> ZK
    ZK --> LOCK

etcd Lock

etcd uses

  • Lease
  • TTL
  • Raft Consensus
flowchart LR
    APP[Application]

    ETCD[(etcd)]

    LOCK[(Distributed Lock)]

    APP --> ETCD
    ETCD --> LOCK

Consul Lock

Consul implements

  • Sessions
  • KV Store
  • Leader Election

Widely used in HashiCorp ecosystem.


Database Lock

Traditional databases support

SELECT *
FROM account
FOR UPDATE;

Useful for

  • Banking
  • Payment Systems

Not ideal for microservices spanning multiple application instances.


Pessimistic Lock

Assume conflict will occur.

Acquire lock first.

Lock

↓

Read

↓

Update

↓

Unlock

Optimistic Lock

Assume conflicts are rare.

Use version numbers.

Version = 5

↓

Update

↓

Version = 6

If another transaction modified the record,

the update fails and retries.


Distributed Scheduler Example

Suppose

Three Spring Boot instances.

Cron Job

Nightly Settlement

Without lock

All three execute.

Result

Duplicate Settlement

With distributed lock

Only one server executes.


Spring Boot Architecture

flowchart TD
    LB[Load Balancer]

    APP1[Spring Boot 1]

    APP2[Spring Boot 2]

    APP3[Spring Boot 3]

    REDIS[(Redis Lock)]

    POSTGRES[(PostgreSQL)]

    LB --> APP1
    LB --> APP2
    LB --> APP3

    APP1 --> REDIS
    APP2 --> REDIS
    APP3 --> REDIS

    APP1 --> POSTGRES
    APP2 --> POSTGRES
    APP3 --> POSTGRES

Banking Example

Distributed Lock

Used for

  • Money Transfer
  • Account Closing
  • Interest Calculation
  • Daily Settlement

Amazon Example

Amazon uses distributed coordination to ensure inventory reservations and order processing are not duplicated across multiple services.


Uber Example

Ride matching uses distributed coordination to prevent assigning the same driver to multiple riders simultaneously.


Netflix Example

Netflix uses distributed coordination for scheduled jobs, metadata updates, and service orchestration.


Kubernetes Example

Leader election and distributed leases ensure only one controller instance actively performs control-plane operations.


Advantages

  • Prevents duplicate processing
  • Prevents overselling
  • Safe distributed scheduling
  • Supports leader election
  • Ensures mutual exclusion
  • Works across multiple servers

Challenges

  • Lock expiration
  • Deadlocks
  • Network failures
  • Lock contention
  • Increased latency
  • Correct lock ownership verification

Monitoring

Monitor

  • Lock Acquisition Time
  • Lock Failures
  • Lock Wait Time
  • Expired Locks
  • Deadlocks
  • Retry Count
  • Redis Latency

Tools

  • Datadog
  • Grafana
  • Prometheus
  • Redis Insight
  • CloudWatch

Common Mistakes

❌ Using Java synchronized across servers

❌ Forgetting lock expiration

❌ Unlocking another process's lock

❌ Long-running critical sections

❌ No retry mechanism

❌ Holding locks during remote API calls


Best Practices

  • Keep critical sections short.
  • Always set a lock expiration (TTL).
  • Release locks in a finally block.
  • Verify lock ownership before unlocking.
  • Prefer Redisson for Spring Boot applications.
  • Use optimistic locking when conflicts are rare.
  • Use pessimistic locking for financial transactions.
  • Monitor lock contention and retries.

Common Interview Questions

What is a Distributed Lock?

A Distributed Lock is a synchronization mechanism that ensures only one application instance can execute a critical section at a time across multiple servers.


Why can't synchronized solve this problem?

Because synchronized works only within a single JVM. It does not coordinate multiple application instances running on different servers.


What is the difference between Redis and ZooKeeper locks?

Redis ZooKeeper
Very fast Strong consistency
Uses TTL Uses ephemeral sequential nodes
Simpler setup Better for coordination
Best for caching & locks Best for distributed coordination

When should distributed locks be used?

Use distributed locks for inventory updates, payment processing, scheduled jobs, leader election, resource allocation, and any operation that must not run concurrently across multiple servers.


Summary

Distributed Locks are essential for coordinating work across multiple application instances. They prevent duplicate processing, protect shared resources, and ensure correctness in distributed systems.

In this article, we covered:

  • Distributed Lock fundamentals
  • Local vs Distributed Locks
  • Lock lifecycle
  • Mutual exclusion
  • Lock expiration
  • Redis locks
  • Redisson
  • ZooKeeper
  • etcd
  • Consul
  • Optimistic vs Pessimistic locking
  • Spring Boot architecture
  • Banking, Amazon, Uber, Netflix, and Kubernetes examples
  • Monitoring
  • Best practices

Distributed Locks are a critical building block for microservices, cloud-native platforms, and distributed systems, enabling safe coordination across multiple nodes while maintaining consistency and reliability.


Loading likes...

Comments

Share a question, correction, or practical insight about this article.

Loading approved comments...