1. <ul id="0c1fb"></ul>

      <noscript id="0c1fb"><video id="0c1fb"></video></noscript>
      <noscript id="0c1fb"><listing id="0c1fb"><thead id="0c1fb"></thead></listing></noscript>

      99热在线精品一区二区三区_国产伦精品一区二区三区女破破_亚洲一区二区三区无码_精品国产欧美日韩另类一区

      RELATEED CONSULTING
      相關(guān)咨詢
      選擇下列產(chǎn)品馬上在線溝通
      服務(wù)時間:8:30-17:00
      你可能遇到了下面的問題
      關(guān)閉右側(cè)工具欄

      新聞中心

      這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
      SpringBoot中怎么實現(xiàn)一個商城秒殺系統(tǒng)

      這篇文章將為大家詳細(xì)講解有關(guān)SpringBoot中怎么實現(xiàn)一個商城秒殺系統(tǒng),文章內(nèi)容質(zhì)量較高,因此小編分享給大家做個參考,希望大家閱讀完這篇文章后對相關(guān)知識有一定的了解。

      專注于為中小企業(yè)提供成都做網(wǎng)站、網(wǎng)站制作服務(wù),電腦端+手機端+微信端的三站合一,更高效的管理,為中小企業(yè)掇刀免費做網(wǎng)站提供優(yōu)質(zhì)的服務(wù)。我們立足成都,凝聚了一批互聯(lián)網(wǎng)行業(yè)人才,有力地推動了成百上千企業(yè)的穩(wěn)健成長,幫助中小企業(yè)通過網(wǎng)站建設(shè)實現(xiàn)規(guī)模擴(kuò)充和轉(zhuǎn)變。

      1.2 環(huán)境

      window下:Zookeeper,redis,rabbitmq-server。jdk1.8以上。

      1.3 介紹

      這里只做秒殺部分功能,其他功能不會涉及。項目運行后可訪問秒殺商品頁面

      當(dāng)用戶沒登陸,點擊詳情會跳轉(zhuǎn)到登陸頁面。

      用戶登陸后可以查看商品的詳情并進(jìn)行搶購。

      注意,用戶對于一件商品只能搶購一次,進(jìn)行第二次搶購時會被拒絕。當(dāng)用戶搶購成功時會異步發(fā)送一封郵件給用戶。

      主要邏輯就是以上。接下來看代碼

      1.4 項目結(jié)構(gòu),api封裝一些枚舉和返回值,model主要是實體類和sql映射文件,service實現(xiàn)業(yè)務(wù)邏輯代碼。

      1.5 顯示秒殺商品到頁面以及用戶的操作使用的還是MVC模式,不細(xì)講。主要看如實現(xiàn)高并發(fā)下的秒殺。

      要細(xì)述的話,東西太多,如果想深入了解,可點擊上面的鏈接。

      基本的秒殺邏輯如下,判斷用戶是否已經(jīng)搶購過該商品,如果沒有則查詢待秒殺商品詳情,判斷該商品是否可以別秒殺,判斷依據(jù)為庫存是否足夠

      如果符合條件,則該商品庫存減1,接著,再一次判斷扣減是否成功,如果扣減成功則生成秒殺成功的訂單,同時通知用戶秒殺成功的信息。

      public Boolean killItem(Integer killId, Integer userId) throws Exception {    Boolean result=false;    //TODO:判斷當(dāng)前用戶是否已經(jīng)搶購過當(dāng)前商品    if (itemKillSuccessMapper.countByKillUserId(killId,userId) <= 0){      //TODO:查詢待秒殺商品詳情      ItemKill itemKill=itemKillMapper.selectById(killId);      //TODO:判斷是否可以被秒殺canKill=1?      if (itemKill!=null && 1==itemKill.getCanKill() ){        //TODO:扣減庫存-減一        int res=itemKillMapper.updateKillItem(killId);        //TODO:扣減是否成功?是-生成秒殺成功的訂單,同時通知用戶秒殺成功的消息        if (res>0){          commonRecordKillSuccessInfo(itemKill,userId);          result=true;        }      }    }else{      throw new Exception("您已經(jīng)搶購過該商品了!");    }    return result;  }

      代碼優(yōu)化1:使用redis的分布式鎖,使用當(dāng)前秒殺商品的id和當(dāng)前用戶的id組成一個key,使用StringBuffer拼接,使用雪花算法生成一個value,存進(jìn)redis中。

      @Autowired  private StringRedisTemplate stringRedisTemplate;  /**   * 商品秒殺核心業(yè)務(wù)邏輯的處理-redis的分布式鎖   * @param killId   * @param userId   * @return   * @throws Exception   */  @Override  public Boolean killItemV3(Integer killId, Integer userId) throws Exception {    Boolean result=false;    if (itemKillSuccessMapper.countByKillUserId(killId,userId) <= 0){      //TODO:借助Redis的原子操作實現(xiàn)分布式鎖-對共享操作-資源進(jìn)行控制      ValueOperations valueOperations=stringRedisTemplate.opsForValue();      final String key=new StringBuffer().append(killId).append(userId).append("-RedisLock").toString();      final String value=RandomUtil.generateOrderCode();      Boolean cacheRes=valueOperations.setIfAbsent(key,value); //luna腳本提供“分布式鎖服務(wù)”,就可以寫在一起      //TOOD:redis部署節(jié)點宕機了      if (cacheRes){        stringRedisTemplate.expire(key,30, TimeUnit.SECONDS);        try {          ItemKill itemKill=itemKillMapper.selectByIdV2(killId);          if (itemKill!=null && 1==itemKill.getCanKill() && itemKill.getTotal()>0){            int res=itemKillMapper.updateKillItemV2(killId);            if (res>0){              commonRecordKillSuccessInfo(itemKill,userId);              result=true;            }          }        }catch (Exception e){          throw new Exception("還沒到搶購日期、已過了搶購時間或已被搶購?fù)戤叄?);        }finally {          if (value.equals(valueOperations.get(key).toString())){            stringRedisTemplate.delete(key);          }        }      }    }else{      throw new Exception("Redis-您已經(jīng)搶購過該商品了!");    }    return result;  }

      代碼優(yōu)化2:將 Boolean cacheRes=lock.tryLock(30,10,TimeUnit.SECONDS); 每隔30秒判斷當(dāng)前用戶是否超時寫在了鎖外面,不會因為一次卡頓而影響整個程序。

      @Autowired  private RedissonClient redissonClient;  /**   * 商品秒殺核心業(yè)務(wù)邏輯的處理-redisson的分布式鎖   * @param killId   * @param userId   * @return   * @throws Exception   */  @Override  public Boolean killItemV4(Integer killId, Integer userId) throws Exception {    Boolean result=false;    final String lockKey=new StringBuffer().append(killId).append(userId).append("-RedissonLock").toString();    RLock lock=redissonClient.getLock(lockKey);    try {      Boolean cacheRes=lock.tryLock(30,10,TimeUnit.SECONDS);      if (cacheRes){        //TODO:核心業(yè)務(wù)邏輯的處理        if (itemKillSuccessMapper.countByKillUserId(killId,userId) <= 0){          ItemKill itemKill=itemKillMapper.selectByIdV2(killId);          if (itemKill!=null && 1==itemKill.getCanKill() && itemKill.getTotal()>0){            int res=itemKillMapper.updateKillItemV2(killId);            if (res>0){              commonRecordKillSuccessInfo(itemKill,userId);              result=true;            }          }        }else{          throw new Exception("redisson-您已經(jīng)搶購過該商品了!");        }      }    }finally {      lock.unlock();      //lock.forceUnlock();    }    return result;  }

      代碼優(yōu)化3:

      @Autowired  private CuratorFramework curatorFramework;  private static final String pathPrefix="/kill/zkLock/";  /**   * 商品秒殺核心業(yè)務(wù)邏輯的處理-基于ZooKeeper的分布式鎖   * @param killId   * @param userId   * @return   * @throws Exception   */  @Override  public Boolean killItemV5(Integer killId, Integer userId) throws Exception {    Boolean result=false;    InterProcessMutex mutex=new InterProcessMutex(curatorFramework,pathPrefix+killId+userId+"-lock");    try {      if (mutex.acquire(10L,TimeUnit.SECONDS)){        //TODO:核心業(yè)務(wù)邏輯        if (itemKillSuccessMapper.countByKillUserId(killId,userId) <= 0){          ItemKill itemKill=itemKillMapper.selectByIdV2(killId);          if (itemKill!=null && 1==itemKill.getCanKill() && itemKill.getTotal()>0){            int res=itemKillMapper.updateKillItemV2(killId);            if (res>0){              commonRecordKillSuccessInfo(itemKill,userId);              result=true;            }          }        }else{          throw new Exception("zookeeper-您已經(jīng)搶購過該商品了!");        }      }    }catch (Exception e){      throw new Exception("還沒到搶購日期、已過了搶購時間或已被搶購?fù)戤叄?);    }finally {      if (mutex!=null){        mutex.release();      }    }    return result;  }

      關(guān)于SpringBoot中怎么實現(xiàn)一個商城秒殺系統(tǒng)就分享到這里了,希望以上內(nèi)容可以對大家有一定的幫助,可以學(xué)到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。


      本文題目:SpringBoot中怎么實現(xiàn)一個商城秒殺系統(tǒng)
      網(wǎng)站網(wǎng)址:http://ef60e0e.cn/article/jphjep.html
      99热在线精品一区二区三区_国产伦精品一区二区三区女破破_亚洲一区二区三区无码_精品国产欧美日韩另类一区
      1. <ul id="0c1fb"></ul>

        <noscript id="0c1fb"><video id="0c1fb"></video></noscript>
        <noscript id="0c1fb"><listing id="0c1fb"><thead id="0c1fb"></thead></listing></noscript>

        施甸县| 萨迦县| 嘉兴市| 郁南县| 浙江省| 迭部县| 共和县| 尖扎县| 道孚县| 绥德县| 元朗区| 柳江县| 如皋市| 曲沃县| 永安市| 苏尼特左旗| 钦州市| 泰来县| 昭苏县| 雷州市| 麟游县| 印江| 建瓯市| 凤城市| 昆山市| 海城市| 镇沅| 库尔勒市| 岗巴县| 肃南| 涞水县| 利辛县| 思南县| 库伦旗| 新河县| 安龙县| 宁远县| 澄江县| 罗平县| 手游| 洪泽县|