Ensuring Idempotency in Spring Boot: Token-Based Approach with Redis
This article explains the concept of idempotency, its importance in distributed systems, and demonstrates a practical implementation in Spring Boot using a token-based annotation, Redis configuration, and sample code, along with testing results that show only one successful response among concurrent requests.
Idempotency Overview
Idempotency originates from mathematics, where the equation f(x)=f(f(x)) holds; in programming it means that repeated identical requests have the same effect on system resources as a single request.
In distributed system design, idempotent interfaces aim to prevent repeated attempts after an exception from causing unacceptable loss.
Token-based mechanisms are commonly used: a unique token is generated for each operation, granting a single execution right; successful execution stores the result, and repeated requests return the same result or an error. (Reference “A Brief Discussion on Idempotency”[1])
Idempotent Implementation
Add Dependency
<dependency>
<groupId>com.pig4cloud.plugin</groupId>
<artifactId>idempotent-spring-boot-starter</artifactId>
<version>0.0.1</version>
</dependency>Configure Redis Connection
By default no configuration is required; the starter supports redisson-spring-boot-starter for full configuration.
spring:
redis:
host: 127.0.0.1
port: 6379API Example
@Idempotent(key = "#key", expireTime = 10, info = "请勿重复查询")
@GetMapping("/test")
public String test(String key) {
return "success";
}Test
10 independent threads send requests.
Result: only one request succeeds.
Backend logs show 9 exceptions, matching expectations.
Idempotent Annotation Details
key : unique identifier for the idempotent operation, expressed with Spring EL using # to reference method parameters; if omitted, the current URL plus arguments are used.
expireTime : validity period (default 1); must be longer than the execution time.
timeUnit : time unit (default seconds).
info : custom message shown when idempotency fails.
delKey : whether to delete the key after business completion (true to delete, false to keep).
Design Principles
Workflow Reference [3]
Before request: check key; if found, return error; if not, store key‑value‑expireTime (key = ip+url+args).
After request: delete the key regardless of its existence; deletion can be configured.
expireTime prevents a stuck request from blocking indefinitely; it must exceed the business execution time.
The solution operates at the interface request layer.
expireTime must be greater than business execution time to avoid repeated requests when the front end lacks a mask or the user navigates away and returns.
Recommend delKey = false so the key remains, enforcing the lock for the entire expireTime.
Implementation idea: the same IP and identical parameters within expireTime allow only one successful execution.
Additional safeguards: front‑end masking, database unique indexes, check‑then‑insert patterns.
The annotation is for idempotency, not for locking; high concurrency stress tests (e.g., 100 parallel requests) are unrealistic in typical scenarios.
Summary
pig-mesh/pig
pig-mesh/idempotent-spring-boot-starter
References
[1] “A Brief Discussion on Idempotency”: https://www.jianshu.com/p/475589f5cd7b
[2] redisson-spring-boot-starter: https://github.com/redisson/redisson/tree/master/redisson-spring-boot-starter
[3] Workflow design reference: https://github.com/it4alla/idempotent
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Java Architecture Diary
Committed to sharing original, high‑quality technical articles; no fluff or promotional content.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
