电商 - 秒杀商品之高并发(1) - 数据库存储

以前做过一个电商项目,有一个积分商城这个活动,因为商品是免费的,积分也很容易获取,这样就造成了商

品很容易被抢光,为了达到用户体验与不超卖,我们是这样实现的!

1.假如我积分商品中的商品是20件,同时200用户进行抢购,为了达到用户体验与不超卖的情况。这个只是举个例子,可以设置商品是100件,10万人进行抢购。

我是这样实现的:

1 . 同时进来200个请求,我只放100个请求,剩下100个请求,就提示,已经抢购完毕,那么还剩下100个请
求,用户体验高了,处理的请求也少了。商品我们则放到Redis里面,里面只存储20个商品,每次更新,与读取都在Redis,当 i < =0 的时候,就提示商品已经抢购完成。

2 . 同样的例子,不过,我们在上面的方法做了一层优化,就是要用户进行拼图,或者输入数字,这样可以避
免有一些用户通过一些手段去抢购,同时也可以达到减轻并发压力问题。

3 . 通过锁的方式,悲观锁,与数据库并行锁,Redis锁,还有的是线程等待时间,这些方法都是可以的,不过,如果加锁,让一个一个进行抢购,会非常慢,用户体验就不好,下面提供例子。

4 .如果用户量超级大,可以用MQ进行消峰。批量操作。

5 .限流,采用IP级别的限流,即针对某一个IP,限制单位时间内发起请求数量。

本章只列出数据存储解决方式:

SQL,直接更新,不去读取,当更新以后,再去读取商品数量,返回给前端!不要在乎说可能会商品真实数量与数据库不符合,其他网站都是这样做的,比如12306,大家应该都用过。

 update tar_commodity set quantity = (quantity - #{quantity}) where id = #{commodityId} and (quantity - #{quantity}) >= 0

实现层lmpl,这里要加事务,更新错误,就回滚
@Transactional

@Override
    public void orderAdd(OrderParam param) {
      try {
          Integer i = commodityMapper.updateOrder(param.getCommodityId(),param.getQuantity());
          System.out.println("I是多少: " + i);
          if(i <= 0){
              System.out.println("库存不足,停止售卖");
              return;
          }
          // 这里反复请求数据,可能会让数据崩溃
          Commodity commodity = commodityMapper.selectOne(new QueryWrapper<>());
          System.out.println("商品数量是: " + commodity.getQuantity());
          System.out.println("售卖中");
      }catch (Exception e){
        System.out.println("库存不足,停止售卖");
      }
    }

看测试图:
在这里插入图片描述

数据库图:
在这里插入图片描述
运行效果图:
在这里插入图片描述
数据库效果图:
在这里插入图片描述
不懂可以加QQ群: 914084240

择其善者而从之,其不善者而改之
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值