Implementing a Redis Distributed Lock with AOP and Automatic Renewal in Spring Boot

This article explains how to protect time‑consuming business operations using a Redis‑based distributed lock in Spring Boot, covering annotation design, AOP pointcut definition, lock acquisition and release, automatic lock renewal with a scheduled executor, and practical testing results.

Top Architect
Top Architect
Top Architect
Implementing a Redis Distributed Lock with AOP and Automatic Renewal in Spring Boot

In many business scenarios a request may involve long‑running operations that need to be locked to prevent concurrent modifications of shared data. Using Redis as a distributed lock allows the lock state to be shared across a cluster, ensuring only one instance can modify the data at a time.

Analysis Process

We create a custom annotation @RedisLockAnnotation to mark methods that require locking, add an AOP pointcut to intercept those methods, and implement an Aspect that performs lock acquisition before method execution and lock release afterwards.

Core Steps

Define the annotation with parameters such as lockFiled, tryCount, typeEnum, and lockTime.

Configure a pointcut using

@Pointcut("@annotation(cn.sevenyuan.demo.aop.lock.RedisLockAnnotation)")

.

In the @Around advice, resolve the method, extract annotation values, generate a unique key, and attempt to set the key in Redis with setIfAbsent.

If the lock is obtained, set an expiration time, add the task to a queue for automatic renewal, execute the business logic, and finally delete the key.

Lock Acquisition

The lock is obtained by calling

redisTemplate.opsForValue().setIfAbsent(businessKey, uniqueValue)

. If the call returns false, an exception is thrown because another thread already holds the lock.

Automatic Renewal ("续时")

A ScheduledExecutorService runs every two seconds, scans the queue of RedisLockDefinitionHolder objects, and extends the expiration of keys that are approaching timeout. The renewal period is calculated as one‑third of the lock timeout.

private static final ScheduledExecutorService SCHEDULER =
    new ScheduledThreadPoolExecutor(1,
        new BasicThreadFactory.Builder()
            .namingPattern("redisLock-schedule-pool")
            .daemon(true)
            .build());

SCHEDULER.scheduleAtFixedRate(() -> {
    Iterator<RedisLockDefinitionHolder> iterator = holderList.iterator();
    while (iterator.hasNext()) {
        RedisLockDefinitionHolder holder = iterator.next();
        if (holder == null) { iterator.remove(); continue; }
        if (redisTemplate.opsForValue().get(holder.getBusinessKey()) == null) {
            iterator.remove(); continue;
        }
        if (holder.getCurrentCount() > holder.getTryCount()) {
            holder.getCurrentTread().interrupt();
            iterator.remove(); continue;
        }
        long curTime = System.currentTimeMillis();
        boolean shouldExtend = (holder.getLastModifyTime() + holder.getModifyPeriod()) <= curTime;
        if (shouldExtend) {
            holder.setLastModifyTime(curTime);
            redisTemplate.expire(holder.getBusinessKey(), holder.getLockTime(), TimeUnit.SECONDS);
            holder.setCurrentCount(holder.getCurrentCount() + 1);
        }
    }
}, 0, 2, TimeUnit.SECONDS);

Testing

A sample controller method annotated with

@RedisLockAnnotation(typeEnum = RedisLockTypeEnum.ONE, lockTime = 3)

simulates a ten‑second sleep. Log output shows the lock being acquired, the renewal attempts, and finally an InterruptedException when the retry limit is exceeded, demonstrating that the lock prevents concurrent execution.

Conclusion

For time‑consuming operations that manipulate critical data, a Redis‑based distributed lock combined with AOP and automatic renewal ensures data consistency and prevents duplicate processing. The article also highlights related concepts such as AOP usage, scheduled thread pools, and thread interruption.

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.

javaconcurrencySpring Boot
Top Architect
Written by

Top Architect

Top Architect focuses on sharing practical architecture knowledge, covering enterprise, system, website, large‑scale distributed, and high‑availability architectures, plus architecture adjustments using internet technologies. We welcome idea‑driven, sharing‑oriented architects to exchange and learn together.

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.