当前位置: 首页 > news >正文

淮南服装网站建设费用wordpress 标签云样式

淮南服装网站建设费用,wordpress 标签云样式,淮北市建设投资有限责任公司,计算机网络网站开发库存超卖问题分析 库存超卖问题其本质就是多个线程操作共享数据产生的线程安全问题,即当一个线程在执行操作共享数据的多条代码的过程中,其他线程也参与了进来,导致了线程安全问题的产生。例如:线程1发送请求,查询库存…

库存超卖问题分析

库存超卖问题其本质就是多个线程操作共享数据产生的线程安全问题,即当一个线程在执行操作共享数据的多条代码的过程中,其他线程也参与了进来,导致了线程安全问题的产生。例如:线程1发送请求,查询库存,发现库存大于1,在还没来及扣除库存时,线程2甚至线程3等发送请求,发现这个数量也是大于1,那么这多个线程都会去扣除库存,最终多个线程都去扣除库存,此时就会出现库存的超卖问题。

image-20230707172612925
image-20230707172612925
  • 多线程安全问题常见的解决方案就是加锁

    • 悲观锁:认为线程安全问题一定会发生,因此在操作数据之前先获取锁,确保线程串行执行,synchronized、lock都属于悲观锁,属于同步锁,让线程串行执行,优点是简单粗暴,缺点是性能一般
    • 乐观锁:认为线程安全问题不一定会发生,只是在更新数据时,判断有没有其他线程对数据做了修改,优点是性能好,缺点是存在成功率问题
      • 如果没有修改,则认为是安全的,该线程进行数据更新
      • 如果已经被其他线程修改,则发生了线程安全问题,此时可以重试或异常
  • 使用乐观锁解决库存超卖问题

    • 乐观锁的关键是判断之前查询得到的数据是否被修改过,常见的方式有两种

      • 版本号法

        • 在数据库等中设置一个版本号字段,每次操作数据会对版本号进行加一操作,当每次读取数据时,读出版本号字段 ,在修改数据的时候,需要判断读出的版本号和数据库是否一致,如果一致,则表明在自己操作该数据的过程中,没有其他线程操作该数据,如果版本号不一致,则表明数据以及被别人修改过了。

          image-20230710111424101
          image-20230710111424101
      • CAS

        • 在扣减库存时,将现在库存和之前查询的库存做对比,如果一样,则说明没有其他线程在中间修改过库存数据,则认为是线程安全的,如果不一样,则说明有线程在中间修改过库存数据。

          image-20230710143222845
          image-20230710143222845

乐观锁解决超卖问题

  • 使用在扣减库存时,将现在库存和之前查询的库存做对比,如果一样,则表明没有人在此中间修改过库存,则认定线程安全,扣除库存

    @Override
    public Long seckillVoucher(Long voucherId) {

        // 查询秒杀优惠券信息
        SeckillVoucher seckillVoucher = seckillVoucherService.getById(voucherId);
        //判断秒杀是否开始和结束
        LocalDateTime beginTime = seckillVoucher.getBeginTime();
        LocalDateTime endTime = seckillVoucher.getEndTime();
        //如果当前时间 在开始时间之后 再结束时间之前 则表明秒杀能进行
        LocalDateTime localDateTime = LocalDateTime.now();
        if ( localDateTime.isBefore(beginTime) || localDateTime.isAfter(endTime) ){
            return null;
        }
        //获取库存量
        Integer stock = seckillVoucher.getStock();
        if (ObjectUtil.isNull(stock) || ObjectUtil.isNotNull(stock) && stock.intValue() <= 0){
            return null;
        }
        //扣减库存 将现在库存和之前查询的库存做对比,如果一样,则表明没有人在此中间修改过库存,则认定线程安全,扣除库存
        boolean update = seckillVoucherService.update(
                new LambdaUpdateWrapper<SeckillVoucher>().setSql("stock = stock - 1").eq(SeckillVoucher::getVoucherId, voucherId)
                        .eq(SeckillVoucher::getStock, stock)
        );
        if (!update){
            return null;
        }
        //创建订单
        VoucherOrder voucherOrder = new VoucherOrder();
        //创建订单ID
        long orderId = redisIdWorker.nextId("order");
        voucherOrder.setId(orderId);
        //获取用户ID
        Long id = UserHolder.getUser().getId();
        voucherOrder.setUserId(id);
        // 代金券id
        voucherOrder.setVoucherId(voucherId);
        this.save(voucherOrder);
        return orderId;
    }

    该方式通过测试能够发现,失败率很高,这主要是由于当多个人都拿到库存时,只有一个能够扣减成功,其他的由于.eq(SeckillVoucher::getStock, stock)无法完成扣减。

    其实在超卖问题中,我们需要保证的是在没用库存的情况下,不能再进行库存扣减,所有需要保证的是库存大于0,所有可以设置.gt(SeckillVoucher::getStock, 0)

    @Override
    public Long seckillVoucher(Long voucherId) {

        // 查询秒杀优惠券信息
        SeckillVoucher seckillVoucher = seckillVoucherService.getById(voucherId);
        //判断秒杀是否开始和结束
        LocalDateTime beginTime = seckillVoucher.getBeginTime();
        LocalDateTime endTime = seckillVoucher.getEndTime();
        //如果当前时间 在开始时间之后 再结束时间之前 则表明秒杀能进行
        LocalDateTime localDateTime = LocalDateTime.now();
        if ( localDateTime.isBefore(beginTime) || localDateTime.isAfter(endTime) ){
            return null;
        }
        //获取库存量
        Integer stock = seckillVoucher.getStock();
        if (ObjectUtil.isNull(stock) || ObjectUtil.isNotNull(stock) && stock.intValue() <= 0){
            return null;
        }
        //扣减库存 将现在库存和之前查询的库存做对比,如果一样,则表明没有人在此中间修改过库存,则认定线程安全,扣除库存
        boolean update = seckillVoucherService.update(
                new LambdaUpdateWrapper<SeckillVoucher>().setSql("stock = stock - 1").eq(SeckillVoucher::getVoucherId, voucherId)
                        .gt(SeckillVoucher::getStock, 0)
        );
        if (!update){
            return null;
        }
        //创建订单
        VoucherOrder voucherOrder = new VoucherOrder();
        //创建订单ID
        long orderId = redisIdWorker.nextId("order");
        voucherOrder.setId(orderId);
        //获取用户ID
        Long id = UserHolder.getUser().getId();
        voucherOrder.setUserId(id);
        // 代金券id
        voucherOrder.setVoucherId(voucherId);
        this.save(voucherOrder);
        return orderId;
    }

本文由 mdnice 多平台发布

http://www.yayakq.cn/news/180749/

相关文章:

  • 51网站统计客户管理系统在哪进入
  • 做网站页面怎么做什么叫国际互联网
  • jsp做的网站代码网站集约化建设通知
  • 1688网站特点租云服务器一个月多少钱
  • 太原优化型网站建设成都文创产品设计公司
  • 电子商务网站设计小结怎么样做长久的电影网站
  • 学网站开发首先学哪些基础wordpress手机版使用
  • 做详情页哪个网站好一个企业网站多少钱
  • 设计师个人网站主页上海智能网站建设
  • 自己做网站要钱么免费域名空间注册
  • 企业营销网站制作深圳做外贸网站的公司
  • 网站网站建设企业wordpress 插件数据
  • 网站建设频教程百度搜索引擎关键词
  • 事业单位网站开发工作规程公司网页制作教程
  • 网站开发项目报告网站建设的空间选择
  • 优惠券网站做代理怎么样哪个网站可以做拼图
  • 石家庄专门做网站wordpress 主题制作视频
  • 济南建站公司效果手机微信网站怎么做的
  • 长沙高端网站建设服务python做网站设计
  • 兰州网站做的好点的公司关于设计图的网站
  • seo网站快速整站优化技术云服务器怎么上传网站
  • 有没有做招聘网站的做柜子好的设计网站
  • 用软件做seo网站关键词推广最新网站建设语言
  • 传统类型的企业网站网络营销的六大特征
  • 弹性云主机做网站如何做英文网站推广
  • 网站的建设哪家好网站分享代码怎么加
  • 用php做图书管理网站兖州城乡建设局网站
  • 衡水网站建设多少钱wordpress 瀑布流布局
  • 营销技巧 第一季北京如何优化搜索引擎
  • 如何将自己做的网站传到网上seo网站营销推广公司