如何防止重复下单

101 阅读1分钟

主要利用一锁二判三更新

提交订单按钮置灰

请求唯一ID+数据库唯一ID

image.png

redis分布式锁+请求唯一ID

创建 Redis 工具类

创建一个 Redis 工具类,用于操作 Redis,例如设置键值对和检查键是否存在:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

import java.util.concurrent.TimeUnit;

@Component
public class RedisUtil {

    @Autowired
    private RedisTemplate<String, Object> redisTemplate;

    /**
     * 设置键值对并设置过期时间
     * @param key 键
     * @param value 值
     * @param timeout 过期时间
     * @param unit 时间单位
     * @return 是否设置成功
     */
    public boolean set(String key, Object value, long timeout, TimeUnit unit) {
        try {
            redisTemplate.opsForValue().set(key, value, timeout, unit);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 判断键是否存在
     * @param key 键
     * @return 是否存在
     */
    public boolean hasKey(String key) {
        try {
            return redisTemplate.hasKey(key);
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }
}

实现防止重复下单逻辑

在订单服务类中,使用 Redis 来检查用户是否已经下单,如果未下单则创建订单并将订单信息存入 Redis,设置一定的过期时间:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.concurrent.TimeUnit;

@Service
public class OrderService {

    @Autowired
    private RedisUtil redisUtil;

    /**
     * 创建订单
     * @param userId 用户ID
     * @return 是否创建成功
     */
    public boolean createOrder(String userId) {
        // 生成Redis键
        String key = "order:" + userId;

        // 检查键是否存在
        if (redisUtil.hasKey(key)) {
            // 键已存在,说明用户已经下单,返回false
            return false;
        }

        // 键不存在,创建订单
        // 模拟订单创建逻辑
        System.out.println("用户 " + userId + " 创建订单成功");

        // 将订单信息存入Redis,设置过期时间为10分钟
        redisUtil.set(key, true, 10, TimeUnit.MINUTES);

        return true;
    }
}

redis分布式锁+token