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
finallyblock. - 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.
Comments
Share a question, correction, or practical insight about this article.
Checking login status...
Loading approved comments...