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

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

 更新時間:2024年12月03日 10:18:25   作者:mxbb.  
文章詳細分析了避免超賣問題的方法,包括確保一人一單的業(yè)務(wù)邏輯,并提供了代碼實現(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)在時間
        LocalDateTime beginTime = seckillVoucher.getBeginTime(); //開始時間
        LocalDateTime endTime = seckillVoucher.getEndTime(); //結(jié)束時間
        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){
            //獲取鎖失敗 返回錯誤或失敗
            return Result.fail("不允許重復下單");
        }
        try {
            //獲取事務(wù)的代理對象
            IVoucherOrderService proxy = (IVoucherOrderService) AopContext.currentProxy();
            return proxy.creatVoucherOrder(voucherId);
        } finally {
            //釋放鎖
            lock.unlock();
        }
        //}//事務(wù)提交之后在釋放鎖
    }
    /**
     * 這里對于加鎖做出一些解釋:如果鎖加在整個方法上,那么就會導
     *  致鎖的粒度過大,導致每個進程進來都會鎖住,所以要控制鎖的粒度
     */
    @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實現(xiàn)限量優(yōu)惠券的秒殺功能的文章就介紹到這了,更多相關(guān)Redis優(yōu)惠券秒殺內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • redis restore 命令的用法實例詳解

    redis restore 命令的用法實例詳解

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

    喀喇沁旗| 景泰县| 黔东| 民勤县| 辛集市| 佳木斯市| 花垣县| 应城市| 信丰县| 芜湖县| 额尔古纳市| 策勒县| 忻州市| 银川市| 淅川县| 宁城县| 姚安县| 中江县| 扬州市| 兴海县| 尉犁县| 元谋县| 阆中市| 法库县| 墨脱县| 石狮市| 宕昌县| 丰都县| 迁西县| 台山市| 长沙县| 正宁县| 临武县| 江城| 合肥市| 子长县| 河南省| 德令哈市| 宿迁市| 荥阳市| 绵竹市|