Backend Development 13 min read

Implementing Request Debounce in Java Backend Using Redis and Redisson

This article explains how to prevent duplicate submissions in Java backend services by implementing request debouncing using custom annotations, Redis-based locks, and Redisson distributed locks, covering key generation, lock acquisition, configuration, and testing to ensure idempotent API calls.

Selected Java Interview Questions
Selected Java Interview Questions
Selected Java Interview Questions
Implementing Request Debounce in Java Backend Using Redis and Redisson

Introduction

The author, a backend Java developer with six years of experience, shares practical techniques for preventing duplicate submissions (debounce) in web APIs, emphasizing both client‑side and server‑side safeguards.

What Is Debounce?

Debounce protects against user‑mistakes and network jitter that can cause the same request to be processed multiple times, potentially creating duplicate data records.

Design Requirements for a Debounce Component

Logical correctness – no false positives.

Fast response – minimal latency.

Easy integration – business logic decoupled.

Clear user feedback – e.g., "You clicked too fast".

Which Interfaces Need Debounce?

User‑input interfaces such as search boxes and form fields.

Button‑click interfaces like form submission or settings save.

Scroll‑loading interfaces such as pull‑to‑refresh or infinite scroll.

How to Identify Duplicate Requests

Determine duplication by a time interval, comparing key parameters, and optionally the request URL.

Distributed Deployment Solutions

1. Shared Cache (Redis)

Use a Redis key with a short TTL; the SET_IF_ABSENT option ensures only the first request succeeds.

StringRedisTemplate.execute(connection ->
    connection.set(lockKey.getBytes(), new byte[0],
        Expiration.from(requestLock.expire(), requestLock.timeUnit()),
        RedisStringCommands.SetOption.SET_IF_ABSENT));

2. Distributed Lock (Redisson)

Redisson provides a lock object that can be tried and, if acquired, held for a configurable period.

RLock lock = redissonClient.getLock(lockKey);
boolean isLocked = lock.tryLock();
if (!isLocked) { throw new BizException(...); }
lock.lock(requestLock.expire(), requestLock.timeUnit());

Implementation Details

A custom annotation @RequestLock defines lock prefix, expiration time, time unit, and key delimiter.

public @interface RequestLock {
    String prefix() default "";
    int expire() default 2;
    TimeUnit timeUnit() default TimeUnit.SECONDS;
    String delimiter() default "&";
}

Parameters that should contribute to the lock key are marked with @RequestKeyParam . The RequestKeyGenerator builds the final key by concatenating annotated parameter values.

public static String getLockKey(ProceedingJoinPoint joinPoint) {
    // ... reflection logic to collect @RequestKeyParam values ...
    return requestLock.prefix() + sb;
}

The AOP aspects RedisRequestLockAspect and RedissonRequestLockAspect intercept methods annotated with @RequestLock , acquire the appropriate lock, execute the original method, and release the lock.

Testing Results

First submission succeeds – "User added successfully".

Rapid repeated submissions are blocked – "Your operation is too fast, please try later".

After the lock expires, a new submission succeeds.

The tests confirm that debounce works, but true idempotency also requires database unique constraints and additional business checks.

Conclusion

By combining custom annotations, Redis or Redisson locks, and careful key generation, backend services can effectively prevent duplicate requests, improve data integrity, and provide a better user experience.

BackendJavaRedisSpringDistributed LockDebounce
Selected Java Interview Questions
Written by

Selected Java Interview Questions

A professional Java tech channel sharing common knowledge to help developers fill gaps. Follow us!

0 followers
Reader feedback

How this landed with the community

login 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.