How to Build a Reliable Redis Distributed Lock with AOP and Auto‑Renewal in Spring Boot

This article walks through the design and implementation of a Redis‑based distributed lock for time‑consuming business operations, covering annotation creation, AOP pointcut setup, lock acquisition and release, timeout handling with a renewal thread, testing, and practical code examples.

IT Architects Alliance
IT Architects Alliance
IT Architects Alliance
How to Build a Reliable Redis Distributed Lock with AOP and Auto‑Renewal in Spring Boot

Background

Some business operations are long‑running and must be executed exclusively to avoid concurrent modifications of database records.

Design Overview

Redis is used as a distributed lock store. A custom annotation @RedisLockAnnotation marks methods that require exclusive execution. An AOP aspect intercepts these methods, generates a unique lock key, attempts to acquire the lock with RedisTemplate.opsForValue().setIfAbsent, and sets an expiration.

Lock acquisition

The aspect extracts the method argument indicated by lockFiled, builds a business key using RedisLockTypeEnum.getUniqueKey, and stores a random UUID as the lock value. If setIfAbsent returns false, an exception is thrown; otherwise redisTemplate.expire(...) sets the lock timeout (default 30 s, configurable via lockTime).

Renewal mechanism

A single‑thread ScheduledExecutorService (daemon) runs every 2 seconds. It iterates a ConcurrentLinkedQueue of RedisLockDefinitionHolder objects, each containing the lock key, lock duration, last renewal timestamp, retry limits and the executing thread. For each holder the scheduler:

Removes entries whose lock key no longer exists in Redis.

If currentCount > tryCount, interrupts the associated thread and removes the holder.

When the remaining time is less than one‑third of the lock timeout, calls redisTemplate.expire to extend the expiration and updates lastModifyTime and currentCount.

Thread interruption

If the renewal thread exceeds the configured retry count, it calls Thread.interrupt() on the business thread. The aspect checks Thread.currentThread().isInterrupted() after the target method returns and throws an InterruptedException to abort the request.

Lock release

In a finally block the aspect always deletes the lock key with redisTemplate.delete(businessKey), guaranteeing release even when exceptions occur.

Key Classes

RedisLockAnnotation

– annotation with attributes lockFiled, tryCount, typeEnum, lockTime. RedisLockTypeEnum – defines a prefix for the lock key (e.g., Business1, Business2) and provides getUniqueKey(String key). RedisLockDefinitionHolder – stores lock metadata required by the renewal thread. RedisLockAspect – AOP aspect containing the pointcut, lock logic, and the static renewal scheduler.

Example Usage

@GetMapping("/testRedisLock")
@RedisLockAnnotation(typeEnum = RedisLockTypeEnum.ONE, lockTime = 3)
public Book testRedisLock(@RequestParam("userId") Long userId) {
    log.info("sleep before");
    Thread.sleep(10000); // simulate long task
    log.info("sleep after");
    return null;
}

The method acquires a lock with a 3‑second timeout. Because the simulated work lasts 10 seconds, the renewal thread extends the lock three times (default retry count). After the fourth attempt the thread is interrupted, causing an InterruptedException and aborting the request.

Observed Log Output

During the test the scheduler logs the business key and retry count at each renewal, and the controller logs an error when the thread is interrupted, confirming that the lock prevented concurrent execution.

Reference

Source code:

https://github.com/Vip-Augus/springboot-note/blob/master/src/main/java/cn/sevenyuan/demo/aop/lock/RedisLockAspect.java
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.

JavaaopredisSpring Bootdistributed-lockScheduledExecutorService
IT Architects Alliance
Written by

IT Architects Alliance

Discussion and exchange on system, internet, large‑scale distributed, high‑availability, and high‑performance architectures, as well as big data, machine learning, AI, and architecture adjustments with internet technologies. Includes real‑world large‑scale architecture case studies. Open to architects who have ideas and enjoy sharing.

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.