最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Redis實(shí)現(xiàn)限量優(yōu)惠券的秒殺功能

 更新時(shí)間:2024年12月03日 10:18:25   作者:mxbb.  
文章詳細(xì)分析了避免超賣問題的方法,包括確保一人一單的業(yè)務(wù)邏輯,并提供了代碼實(shí)現(xiàn)步驟和代碼示例,感興趣的朋友跟隨小編一起看看吧

核心:避免超賣問題,保證一人一單  業(yè)務(wù)邏輯

代碼步驟分析

全部代碼

@Service
public class VoucherOrderServiceImpl extends ServiceImpl<VoucherOrderMapper, VoucherOrder> implements IVoucherOrderService {
    @Resource
    private ISeckillVoucherService seckillVoucherService;
    @Resource
    private RedisIdWorker redisIdWorker;
    @Resource
    private StringRedisTemplate stringRedisTemplate;
    @Resource
    private RedissonClient redissonClient;
    @Override
    public Result seckillVoucher(Long voucherId) {
        //1 查詢優(yōu)惠券信息
        SeckillVoucher seckillVoucher = seckillVoucherService.getById(voucherId);
        //2 判斷秒殺是否開始
        LocalDateTime now = LocalDateTime.now(); //現(xiàn)在時(shí)間
        LocalDateTime beginTime = seckillVoucher.getBeginTime(); //開始時(shí)間
        LocalDateTime endTime = seckillVoucher.getEndTime(); //結(jié)束時(shí)間
        if (now.isBefore(beginTime)) {
            return Result.fail("秒殺還未開始");
        }
        //3 判斷秒殺是否結(jié)束
        if (now.isAfter(endTime)) {
            return Result.fail("秒殺已結(jié)束");
        }
        //4 判斷庫存是否充足
        int stock = (int) seckillVoucher.getStock();
        if (stock == 0 && stock <= 0) {
            return Result.fail("庫存不足");
        }
        //確保一人一單 用戶ID和代金券ID聯(lián)合查詢
        Long userId = UserHolder.getUser().getId();
        //先獲取鎖 再提交事務(wù)
        //synchronized (userId.toString().intern()) {
        //創(chuàng)建鎖對象
        //SimpleRedisLock simpleRedisLock = new SimpleRedisLock("order:" + userId, stringRedisTemplate);
        RLock lock = redissonClient.getLock("lock:order:" + userId);
        //獲取鎖
        boolean isLock = lock.tryLock();
        //判斷是否獲取鎖成功
        if (!isLock){
            //獲取鎖失敗 返回錯(cuò)誤或失敗
            return Result.fail("不允許重復(fù)下單");
        }
        try {
            //獲取事務(wù)的代理對象
            IVoucherOrderService proxy = (IVoucherOrderService) AopContext.currentProxy();
            return proxy.creatVoucherOrder(voucherId);
        } finally {
            //釋放鎖
            lock.unlock();
        }
        //}//事務(wù)提交之后在釋放鎖
    }
    /**
     * 這里對于加鎖做出一些解釋:如果鎖加在整個(gè)方法上,那么就會(huì)導(dǎo)
     *  致鎖的粒度過大,導(dǎo)致每個(gè)進(jìn)程進(jìn)來都會(huì)鎖住,所以要控制鎖的粒度
     */
    @Transactional
    public Result creatVoucherOrder(Long voucherId) {
        Long userId = UserHolder.getUser().getId();
        Integer count = query().eq("user_id", userId).eq("voucher_id", voucherId).count();
        if (count > 0) {
            return Result.fail("用戶已經(jīng)購買過了");
        }
        //5 扣減庫存-
        boolean success = seckillVoucherService.update()
                .setSql("stock = stock -1 ")  //樂觀鎖
                .eq("voucher_id", voucherId).gt("stock", 0) //判斷庫存是否大于0: where id = ? and stock > 0
                .update();
        if (!success) {
            return Result.fail("庫存不足");
        }
        //6 創(chuàng)建訂單
        //6.1 訂單ID
        VoucherOrder voucherOrder = new VoucherOrder();
        long orderid = RedisIdWorker.nextId("order");
        voucherOrder.setVoucherId(orderid);
        //6.2 用戶ID
        voucherOrder.setUserId(userId);
        //6.3 代金券ID
        voucherOrder.setVoucherId(voucherId);
        save(voucherOrder);
        //7 返回訂單id
        return Result.ok(orderid);
    }
}

到此這篇關(guān)于Redis實(shí)現(xiàn)限量優(yōu)惠券的秒殺功能的文章就介紹到這了,更多相關(guān)Redis優(yōu)惠券秒殺內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • redis restore 命令的用法實(shí)例詳解

    redis restore 命令的用法實(shí)例詳解

    Redis的RESTORE命令用于將DUMP生成的序列化數(shù)據(jù)恢復(fù)為鍵值,適用于數(shù)據(jù)遷移、備份恢復(fù)和跨實(shí)例同步,本文介紹redis restore 命令的用法,感興趣的朋友一起看看吧
    2025-02-02
  • 最新評論

    页游| 阆中市| 依兰县| 阜阳市| 长宁县| 新闻| 安化县| 中西区| 手机| 江城| 左云县| 明光市| 宁阳县| 广昌县| 慈利县| 鹿邑县| 公安县| 虞城县| 嵊泗县| 镶黄旗| 伊宁县| 新平| 和静县| 盐亭县| 玉溪市| 泰来县| 金秀| 牟定县| 开远市| 桃江县| 马边| 新干县| 专栏| 乐昌市| 临江市| 措美县| 阿荣旗| 芦山县| 禄劝| 五河县| 和田县|