Understanding Distributed Locks: Concepts, Requirements, and Implementation Methods

This article explains why distributed locks are essential for maintaining data consistency in distributed systems, outlines their key requirements, and compares three common implementation approaches—database‑based, Redis‑based, and ZooKeeper‑based—complete with code examples and practical considerations.

Architecture Digest
Architecture Digest
Architecture Digest
Understanding Distributed Locks: Concepts, Requirements, and Implementation Methods

Most internet systems are deployed in a distributed manner, which improves performance and efficiency but also introduces the challenge of maintaining data consistency across multiple nodes.

When a resource is shared among multiple systems, only one client should access it at a time; otherwise concurrent reads and writes can lead to inconsistent data.

1. Why Do We Need Distributed Locks?

In the single‑machine era, thread‑level locks (e.g., synchronize or Lock in Java) suffice because resources are shared within a process. In distributed systems, resources are shared across processes on different machines, rendering thread‑level locks ineffective, so a distributed lock mechanism is required.

A distributed lock ensures mutual exclusion for shared resources in a multi‑client environment.

Key requirements for a distributed lock are:

Exclusivity: only one client can hold the lock at any moment.

Deadlock avoidance: the lock must be released after a bounded time, either normally or due to failure.

High availability: lock acquisition and release must be reliable and performant.

2. Common Implementation Methods

The three mainstream approaches, ordered by increasing implementation complexity, are:

Database‑based locks

Redis‑based locks

ZooKeeper‑based locks

Each method has trade‑offs and should be chosen based on specific business scenarios.

2.1 Database‑Based Locks

Two typical strategies are used:

Optimistic lock (version field)

Pessimistic lock (row‑level FOR UPDATE)

Optimistic lock example: A version column is added to a table. When reading a row, the current version is retrieved. On update, the version is incremented and the update succeeds only if the stored version matches the original one; otherwise the update fails, indicating a concurrent modification.

Illustrative scenario: two users withdraw from the same account concurrently. Both read the balance (2000) and version=1. The first update increments the version to 2; the second update sees version=2 and aborts, forcing a retry.

Requirements for optimistic locking:

The lock service must provide an incrementing version number.

Each update must verify the version before writing the new data.

Pessimistic lock example (MySQL):

public boolean lock() {
    connection.setAutoCommit(false);
    while (true) {
        ResultSet rs = connection.executeQuery("SELECT * FROM user WHERE id = 100 FOR UPDATE");
        if (rs.next()) {
            // lock acquired
            return true;
        }
        Thread.sleep(1000);
    }
    // return false if lock not acquired
}
// Release lock
connection.commit();

Note: In InnoDB, only indexed columns can acquire row‑level locks; otherwise a table‑level lock is used.

2.2 Redis‑Based Locks

Redis provides atomic commands that can be used to implement locks. The common pattern uses the SET key value NX PX ttl command (available from Redis 2.6.12): SET user_key user_value NX PX 100 This command sets user_key only if it does not already exist and sets an expiration of 100 ms. Because only one client can successfully set the key, it acts as a lock.

After acquiring the lock, the client performs its business logic and releases the lock by deleting the key, ensuring that the value matches the one it set. For Redis clusters, the Redlock algorithm can be used.

2.3 ZooKeeper‑Based Locks

ZooKeeper implements distributed locks using temporary sequential nodes. A client creates a temporary sequential node under a designated lock directory and checks if its node has the smallest sequence number. If it does, the client holds the lock; otherwise it watches the next smaller node and retries when that node is deleted.

Releasing the lock simply deletes the temporary node.

Images in the original article illustrate the ZooKeeper lock hierarchy and the client‑node relationship.

In summary, distributed locks are crucial for ensuring data consistency in distributed environments, and the choice among database, Redis, or ZooKeeper implementations depends on factors such as performance requirements, fault tolerance, and operational complexity.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

databasedistributed-lock
Architecture Digest
Written by

Architecture Digest

Focusing on Java backend development, covering application architecture from top-tier internet companies (high availability, high performance, high stability), big data, machine learning, Java architecture, and other popular fields.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.