模块5之实现前端页面对秒杀结果的轮询
简介
当秒杀请求被放入queue中后,由于MySQL处理能力有限,可能需要等待一段时间才能完成对秒杀请求的处理;这段时间前端会不断询问秒杀请求的处理结果。
1.在前端定义轮询函数。
每隔50ms,调用“/miaosha/getresult”接口,传入参数goodsId,当秒杀成功时提示是否查看订单页面,当秒杀失败是显示失败信息,当秒杀请求
仍在处理中时,等待50ms后再次查询。
1 //轮询功能:每隔50ms,查看一次是否秒杀成功 2 function getResult(goodsId) { 3 g_showLoading(); 4 $.ajax({ 5 url:"/miaosha/getresult", 6 type:"GET", 7 data:{ 8 goodsId:$("#goodsId").val(), 9 }, 10 success:function (data){ 11 var result = data.data; 12 if (result<0){ 13 layer.msg("对不起,秒杀失败"); 14 }else if (result==0){ 15 setTimeout(function () { 16 getResult(goodsId); 17 },50) 18 } else { 19 layer.confirm("恭喜你,秒杀成功。查看订单?",{btn:["确定","取消"]}, 20 function () { 21 window.location.href="/order_detail.htm?orderId="+result; 22 }, 23 function () { 24 layer.closeAll(); 25 26 }); 27 } 28 29 }, 30 error:function () { 31 layer.msg(data.msg); 32 } 33 }); 34 35 }
2.后端getResult方法会返回秒杀的处理结果
成功:返回订单id;失败:返回-1,表示没有库存了;正在处理中:返回0。
1 /* 2 * 轮询功能:查看秒杀的结果 3 * */ 4 @AccessLimit(seconds = 5,maxCount = 5) 5 @RequestMapping(value = "/getresult",method = RequestMethod.GET) 6 @ResponseBody 7 public Result<Long> getResult(Model model,MiaoshaUser user,@RequestParam("goodsId")long goodsId) { 8 //判断现在的秒杀状态 9 long result = miaoshaService.getMiaoshaResult(user.getId(),goodsId); 10 11 return Result.success(result); 12 }
3.miaoshaService.java中的getMiaoshaResult()方法才是真正获取秒杀结果的方法
该方法的参数有两个,goodsId,userId。此两个参数将被用来查询使用。
在该方法中进行两次判断,第一次,goodsId+userId相对应的秒杀订单是否存在,存在返回订单号;不存在,进行第二次
第二次,判断减库存的情况,减库存失败就返回秒杀失败,其它的情况就认为正在处理中。
1 //轮询中判断秒杀的状态 2 public long getMiaoshaResult(Long userId, long goodsId) { 3 //1.判断秒杀是否成功 4 OrderInfo orderInfo = orderInfoService.getByUserIdGoodsId(userId,goodsId); 5 if (orderInfo != null) { 6 return orderInfo.getId(); //秒杀成功返回订单id 7 } 8 //2.如果不成功,判断是否秒杀失败或秒杀进行中 9 if (!getReduceResult(goodsId)) { 10 return -1; //没有库存,秒杀失败 11 }else return 0; //有库存,正在秒杀 12 }
在第二次判断中,需要使用getResult()函数,此函数为获取减库存结果的函数,并且还有一个与之对应的setResult()函数用来保存减库存结果。
1 private void setReduceResult(long goodsId, boolean reduceResult) { 2 redisService.set(ReduceResultPrefix.getReduceResult,""+goodsId,reduceResult); 3 } 4 5 private boolean getReduceResult(long goodsId) { 6 return redisService.exists(ReduceResultPrefix.getReduceResult,""+goodsId); 7 }
在减库存的操作过后调用setReduceResult方法,将减库存的结果,缓存到redis中。
1 //三步走:减库存,下订单,写入秒杀订单 2 @Transactional 3 public OrderInfo miaoSha(long useId, long goodsId) { 4 //减库存,并设置减库存的结果 5 boolean reduceResult=miaoshaGoodsService.reduceStock(goodsId); 6 miaoshaGoodsService.reduceFMStock(goodsId); 7 setReduceResult(goodsId,reduceResult); 8 if (!reduceResult) { 9 return null; 10 }
其中miaoshaGoodsService.reduceStock(goodsId);会调用ORM框架的update操作去减库存;
而update操作会返回影响的行数,如果返回值为1,代表减库存成功;返回值为0,代表减库存失败。
在miaoshaGoodsService.reduceStock()方法中会将0,1转化为false,true作为返回值,然后赋值给reduceResult变量。
然后将reduceResult变量缓存入redis中。
posted on 2020-04-13 20:46 hello,bdiskl 阅读(1310) 评论(0) 编辑 收藏 举报