How to Ensure Concurrency Quality with Distributed Locks in E‑Commerce Systems

This article explains why concurrency issues like overselling occur in e‑commerce, introduces distributed lock concepts and mainstream implementations (MySQL, Redis, Zookeeper/etcd), and provides a three‑stage quality‑assurance framework with code‑review checklists, testing methods, and data‑reconciliation techniques.

dbaplus Community
dbaplus Community
dbaplus Community
How to Ensure Concurrency Quality with Distributed Locks in E‑Commerce Systems

Background

Concurrency problems are among the most common issues in e‑commerce systems, leading to overselling, duplicate lottery draws, excessive coupon issuance, and inconsistent points. These arise when multiple machines modify the same shared resource simultaneously, causing data chaos unless properly restricted. Distributed locks are a widely used solution for guaranteeing data consistency.

What Is a Distributed Lock?

In a single‑machine environment, a lock synchronizes threads so that only one can modify a variable or code block at a time. A distributed lock extends this concept to multi‑machine systems by providing a globally visible marker that indicates ownership of a shared resource.

Mainstream Distributed‑Lock Implementations

There are three major ways to implement a distributed lock:

Database‑based lock (MySQL) : table lock or optimistic lock using a version column.

Cache‑based lock (Redis) : setnx command with expiration.

Zookeeper/etcd lock : coordination service providing exclusive access.

Detailed implementations are covered in many articles and are not repeated here.

Quality Assurance for Concurrency

1. Pre‑Implementation Review

During technical review, assess whether the business scenario presents concurrency risk and choose the appropriate lock technology based on its advantages and limitations.

2. In‑Process Assurance (Code Review)

Redis‑based lock checklist :

Redis Key : Use a consistent key that uniquely identifies the shared resource (e.g., per‑product inventory).

Lock Release : Release the lock in a finally block; only the lock owner may release it.

Lock Timeout : Set an expiration to avoid deadlocks; consider atomic release via Lua script if needed.

Lock Granularity : Include any read‑only resources needed for computation to prevent dirty reads.

Acquisition Failure : Handle failure by throwing an exception, spinning, or using pub/sub; choose the strategy based on concurrency level.

MySQL lock checklist :

Optimistic lock (version column) : Add a numeric version field, compare and increment on update; if the version mismatches, the update fails and must be retried.

Table lock : Create a lock table with a unique constraint; insert a row to acquire the lock and delete it to release. Generally not recommended.

3. Post‑Implementation Assurance (Data Reconciliation)

After deployment, perform data reconciliation to verify consistency. Example SQL to detect duplicate task records:

select count(*) as task_count, scene_code, order_id
  from task_record
 where unique_id is not null
group by scene_code, order_id
 having count(*) > 1;

Concurrency Testing

Testing can be categorized into three types:

Complex scenarios with multiple dependent resources – require carefully designed link‑level load tests.

Repeated single‑resource calls (e.g., inventory deduction) – can be tested via API load testing.

Single‑resource single‑call scenarios (e.g., one‑time lottery) – verify that duplicate attempts are prevented.

Tools: JMeter, CountDownLatch, CyclicBarrier. Example Java code using CountDownLatch:

public void invokeAllTask(ConcurrencyRequest request, Runnable task) {
    final CountDownLatch startCountDownLatch = new CountDownLatch(1);
    final CountDownLatch endCountDownLatch = new CountDownLatch(request.getConcurrency());
    for (int i = 0; i < request.getConcurrency(); i++) {
        Thread t = new Thread(() -> {
            try {
                startCountDownLatch.await();
                try {
                    task.run();
                } finally {
                    endCountDownLatch.countDown();
                }
            } catch (Exception ex) {
                log.error("异常", ex);
            }
        });
        t.start();
    }
    startCountDownLatch.countDown();
    try {
        endCountDownLatch.await();
    } catch (InterruptedException ex) {
        log.error("线程异常中断", ex);
    }
}

Conclusion

Effective concurrency quality assurance follows four principles:

Systematically identify concurrency scenarios.

Apply a detailed code‑review checklist for lock implementation.

Conduct appropriate concurrency testing where feasible.

Monitor production data and perform reconciliation to catch residual issues.

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.

Backende‑commercetestingconcurrencyredisCode reviewmysqldistributed-lock
dbaplus Community
Written by

dbaplus Community

Enterprise-level professional community for Database, BigData, and AIOps. Daily original articles, weekly online tech talks, monthly offline salons, and quarterly XCOPS&DAMS conferences—delivered by industry experts.

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.