Implementing a High‑Concurrency Flash Sale System Using Redis List Queues in Spring Boot
This article explains why common Redis‑based flash‑sale demos that rely on WATCH transactions, distributed locks, or Lua scripts are unreliable, and presents a simple, lock‑free solution using Redis list operations (LPUSH/RPOP) with Spring Boot's StringRedisTemplate, including full Java code and usage examples.
When building a flash‑sale (秒杀) system where, for example, 100 phones are sold on a first‑come‑first‑served basis, many publicly available Java demos use Redis WATCH transactions, distributed locks, or scripts, but they often fail under high concurrency because they lack retry logic and introduce heavy contention.
The article first critiques three typical approaches:
WATCH‑based optimistic locking – only one of many concurrent requests succeeds, the rest fail without retry.
Redis‑based distributed lock (SETNX) – only one client obtains the lock, the others fail, and retry mechanisms are rarely implemented.
Lua or other script solutions – opaque and difficult to understand, especially for developers unfamiliar with C‑style languages.
To avoid these problems, the author proposes a lock‑free design that leverages Redis' single‑threaded nature and its list data structure. By pushing all sale items into a Redis list (LPUSH) before the sale starts and letting each request pop an item from the right side (RPOP), the system guarantees atomicity without explicit locks, and the return value directly indicates success (item popped) or failure (null).
The core implementation is a Spring service built on StringRedisTemplate . The utility class provides methods to add strings with expiration, retrieve strings, delete keys, push a collection of items to the left of a list, and pop an item from the right of a list. The relevant code is shown below:
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import java.time.Duration;
import java.util.Collection;
@Service
public class RedisServiceImpl
implements RedisService
{
@Autowired
private StringRedisTemplate stringRedisTemplate;
// Add a string with expiration
@Override
public void addString(String key, String value, Duration duration) {
stringRedisTemplate.opsForValue().set(key, value, duration);
}
// Find a string by key
@Override
public String findString(String key) {
return stringRedisTemplate.opsForValue().get(key);
}
// Delete a key
@Override
public Boolean deleteByKey(String key) {
return stringRedisTemplate.delete(key);
}
// Pop one element from the right side of a list
@Override
public String removeOneEntryOnListRight(String listName) {
return stringRedisTemplate.opsForList().rightPop(listName);
}
// Push a collection of elements to the left side of a list (creates the list if it does not exist)
@Override
public Long addEntriesOnListLeft(String listName, Collection
args) {
return stringRedisTemplate.opsForList().leftPushAll(listName, args);
}
}Usage example – initializing the queue with 100 items before the sale:
List
entriesList = new LinkedList<>();
for (int i = 0; i < 100; i++) {
entriesList.add("某个商品");
}
redisService.addEntriesOnListLeft("queueName", entriesList);During the flash sale, each request simply attempts to pop an item:
String redisResult = redisService.removeOneEntryOnListRight("queueName");
if (redisResult == null) {
// No item obtained – the request failed to secure the product
} else {
// Item obtained – proceed with order processing
}This approach eliminates lock‑related bottlenecks, scales well even to tens of thousands of concurrent requests, and requires minimal code changes if the product catalog or quantity changes – you only need to adjust the list contents in Redis.
Finally, the author invites readers to discuss the design, ask questions, and join a community of architects, while also providing links to additional resources and interview material.
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.
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.