模塊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中。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM