1,页面缓存:缓存时间比较短,适合短时间内变化不大的数据,如查询商品列表的页面以及商品详情添加缓存

秒杀-页面缓存 ,对象缓存,秒杀超买问题 随笔 第1张
    @RequestMapping(value="/to_list",produces = "text/html")
    @ResponseBody
    public String list(HttpServletRequest request, HttpServletResponse response,Model model, MiaoshaUser user) {
        model.addAttribute("user", user);

        //  取缓存
        String html = redisService.get(GoodsKey.getByList, "", String.class);
        if(StringUtils.isNotEmpty(html)){
            return html;
        }
        List<GoodsVo> goodsList = goodsService.listGoodsVo();
        model.addAttribute("goodsList", goodsList);
//         return "goods_list";

        SpringWebContext ctx = new SpringWebContext(request,response,
                request.getServletContext(),request.getLocale(), model.asMap(), applicationContext );
        //手动渲染
        html = thymeleafViewResolver.getTemplateEngine().process("goods_list", ctx);
        if(StringUtils.isNotEmpty(html)){
            redisService.set(GoodsKey.getByList,"",html);
        }
        return html;

    }
View Code

   

SRE实战 互联网时代守护先锋,助力企业售后服务体系运筹帷幄!一键直达领取阿里云限量特价优惠。 秒杀-页面缓存 ,对象缓存,秒杀超买问题 随笔 第3张
 @RequestMapping(value = "/to_detail/{goodsId}",produces = "text/html")
    @ResponseBody
    public String detail(HttpServletRequest request, HttpServletResponse response,Model model,MiaoshaUser user,
            @PathVariable("goodsId")long goodsId) {
        model.addAttribute("user", user);
        //  取缓存
        String html = redisService.get(GoodsKey.getByGoodsDetail, ""+goodsId, String.class);
        if(StringUtils.isNotEmpty(html)){
            return html;
        }

        GoodsVo goods = goodsService.getGoodsVoByGoodsId(goodsId);
        model.addAttribute("goods", goods);
        
        long startAt = goods.getStartDate().getTime();
        long endAt = goods.getEndDate().getTime();
        long now = System.currentTimeMillis();
        
        int miaoshaStatus = 0;
        int remainSeconds = 0;
        if(now < startAt ) {//秒杀还没开始,倒计时
            miaoshaStatus = 0;
            remainSeconds = (int)((startAt - now )/1000);
        }else  if(now > endAt){//秒杀已经结束
            miaoshaStatus = 2;
            remainSeconds = -1;
        }else {//秒杀进行中
            miaoshaStatus = 1;
            remainSeconds = 0;
        }
        model.addAttribute("miaoshaStatus", miaoshaStatus);
        model.addAttribute("remainSeconds", remainSeconds);

        SpringWebContext sc= new SpringWebContext(request,response,request.getServletContext(),request.getLocale(),model.asMap(),applicationContext);
        //手动渲染
        html = thymeleafViewResolver.getTemplateEngine().process("goods_detail", sc);
        if(StringUtils.isNotEmpty(html)){
            redisService.set(GoodsKey.getByGoodsDetail,""+goodsId,html);
        }
        return html;
    }
View Code

 

2.对象缓存,把时间设置成永久(0),

秒杀-页面缓存 ,对象缓存,秒杀超买问题 随笔 第5张
public MiaoshaUser getById(long id) {
        //取缓存
        MiaoshaUser user = redisService.get(MiaoshaUserKey.getById, "" + id, MiaoshaUser.class);
        if(user!=null){
            return user;
        }
         user = miaoshaUserDao.getById(id);
        if(user!=null){
            redisService.set(MiaoshaUserKey.getById,""+id,user);
        }

        return user;
    }
    
View Code

但是在有数据更新的时候要注意缓存的更新问题,否则会出现缓存不一致的现象,必须先更新数据库,再更新缓存,顺序不可以颠倒,否则容易出现数据不一致的问题

秒杀-页面缓存 ,对象缓存,秒杀超买问题 随笔 第7张
public boolean updatePassword(String token,long id, String formPass){
        //获取user
        MiaoshaUser user = redisService.get(MiaoshaUserKey.getById, "" + id, MiaoshaUser.class);
        if(user==null){
            throw new GlobalException(CodeMsg.MOBILE_NOT_EXIST);
        }
        MiaoshaUser miaoshaUser=new MiaoshaUser();
        miaoshaUser.setPassword(MD5Util.formPassToDBPass(formPass,user.getSalt()));
        miaoshaUser.setId(id);
        miaoshaUserDao.update(miaoshaUser);

        //更新缓存
        redisService.delete(MiaoshaUserKey.getById,""+id);
        user.setPassword(miaoshaUser.getPassword());
        redisService.set(MiaoshaUserKey.token,token,user);
        return true;

    }
View Code

 

3.秒杀前先判断是否还有库存,其次判断是否已经秒杀到,再减库存“update miaosha_goods set stock_count=stock_count-1 where goods_id=#{goodsId} and stock_count>0”

秒杀-页面缓存 ,对象缓存,秒杀超买问题 随笔 第9张
 @RequestMapping(value="/do_miaosha", method=RequestMethod.POST)
    @ResponseBody
    public Result<OrderInfo> miaosha(Model model,MiaoshaUser user,
            @RequestParam("goodsId")long goodsId) {
        model.addAttribute("user", user);
        if(user == null) {
            return Result.error(CodeMsg.SESSION_ERROR);
        }
        //判断库存
        GoodsVo goods = goodsService.getGoodsVoByGoodsId(goodsId);//10个商品,req1 req2
        int stock = goods.getStockCount();
        if(stock <= 0) {
            return Result.error(CodeMsg.MIAO_SHA_OVER);
        }
        //判断是否已经秒杀到了
        MiaoshaOrder order = orderService.getMiaoshaOrderByUserIdGoodsId(user.getId(), goodsId);
        if(order != null) {
            return Result.error(CodeMsg.REPEATE_MIAOSHA);
        }
        //减库存 下订单 写入秒杀订单
        OrderInfo orderInfo = miaoshaService.miaosha(user, goods);
        return Result.success(orderInfo);
    }
View Code

 

扫码关注我们
微信号:SRE实战
拒绝背锅 运筹帷幄