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

网站人多怎么优化网站建设用什么程序语言

网站人多怎么优化,网站建设用什么程序语言,软件工程师招聘简章pdf,百度蜘蛛优惠券秒杀一人一单 前言一、需求以及之前存在的问题二、增加一人一单逻辑1.初步代码2.封装一人一单逻辑3.控制锁的粒度 三、事务控制问题四、总结 前言 跟随黑马虎哥学习redis#xff1a; 这是我认为b站上最好的redis教程#xff0c;各方面讲解透彻#xff0c;知识点覆盖… 优惠券秒杀一人一单 前言一、需求以及之前存在的问题二、增加一人一单逻辑1.初步代码2.封装一人一单逻辑3.控制锁的粒度 三、事务控制问题四、总结 前言 跟随黑马虎哥学习redis 这是我认为b站上最好的redis教程各方面讲解透彻知识点覆盖比较全。 黑马redis视频链接B站黑马redis教学视频 本文参考黑马redis课程笔记。 一、需求以及之前存在的问题 需求修改秒杀业务要求同一个优惠券一个用户只能下一单。 之前的问题 优惠卷是为了引流但是目前的情况是一个人可以无限制的抢这个优惠卷所以我们应当增加一层逻辑让一个用户只能下一个单而不是让一个用户下多个单。 具体操作逻辑如下比如时间是否充足如果时间充足则进一步判断库存是否足够然后再根据优惠卷id和用户id查询是否已经下过这个订单如果下过这个订单则不再下单否则进行下单。 二、增加一人一单逻辑 实现流程 1.初步代码 Override public Result seckillVoucher(Long voucherId) {// 1.查询优惠券SeckillVoucher voucher seckillVoucherService.getById(voucherId);// 2.判断秒杀是否开始if (voucher.getBeginTime().isAfter(LocalDateTime.now())) {// 尚未开始return Result.fail(秒杀尚未开始);}// 3.判断秒杀是否已经结束if (voucher.getEndTime().isBefore(LocalDateTime.now())) {// 尚未开始return Result.fail(秒杀已经结束);}// 4.判断库存是否充足if (voucher.getStock() 1) {// 库存不足return Result.fail(库存不足);}// 5.一人一单逻辑// 5.1.用户idLong userId UserHolder.getUser().getId();int count query().eq(user_id, userId).eq(voucher_id, voucherId).count();// 5.2.判断是否存在if (count 0) {// 用户已经购买过了return Result.fail(用户已经购买过一次);}//6扣减库存boolean success seckillVoucherService.update().setSql(stock stock -1).eq(voucher_id, voucherId).update();if (!success) {//扣减库存return Result.fail(库存不足);}//7.创建订单VoucherOrder voucherOrder new VoucherOrder();// 7.1.订单idlong orderId redisIdWorker.nextId(order);voucherOrder.setId(orderId);voucherOrder.setUserId(userId);// 7.3.代金券idvoucherOrder.setVoucherId(voucherId);save(voucherOrder);return Result.ok(orderId);}存在问题 现在的问题还是和之前一样并发过来查询数据库都不存在订单所以我们还是需要加锁但是乐观锁比较适合更新数据而现在是插入数据所以我们需要使用悲观锁操作 注意 在这里提到了非常多的问题我们需要慢慢的来思考首先我们的初始方案是封装了一个createVoucherOrder方法同时为了确保他线程安全在方法上添加了一把synchronized 锁 2.封装一人一单逻辑 Transactional public synchronized Result createVoucherOrder(Long voucherId) {Long userId UserHolder.getUser().getId();// 5.1.查询订单int count query().eq(user_id, userId).eq(voucher_id, voucherId).count();// 5.2.判断是否存在if (count 0) {// 用户已经购买过了return Result.fail(用户已经购买过一次);}// 6.扣减库存boolean success seckillVoucherService.update().setSql(stock stock - 1) // set stock stock - 1.eq(voucher_id, voucherId).gt(stock, 0) // where id ? and stock 0.update();if (!success) {// 扣减失败return Result.fail(库存不足);}// 7.创建订单VoucherOrder voucherOrder new VoucherOrder();// 7.1.订单idlong orderId redisIdWorker.nextId(order);voucherOrder.setId(orderId);// 7.2.用户idvoucherOrder.setUserId(userId);// 7.3.代金券idvoucherOrder.setVoucherId(voucherId);save(voucherOrder);// 7.返回订单idreturn Result.ok(orderId); }此时面临的问题 这样添加锁锁的粒度太粗了在使用锁过程中控制锁粒度 是一个非常重要的事情因为如果锁的粒度太大会导致每个线程进来都会锁住。 3.控制锁的粒度 intern() 这个方法是从常量池中拿到数据如果我们直接使用userId.toString() 他拿到的对象实际上是不同的对象new出来的对象我们使用锁必须保证锁必须是同一把所以我们需要使用intern()方法 Transactional public Result createVoucherOrder(Long voucherId) {Long userId UserHolder.getUser().getId();synchronized(userId.toString().intern()){// 5.1.查询订单int count query().eq(user_id, userId).eq(voucher_id, voucherId).count();// 5.2.判断是否存在if (count 0) {// 用户已经购买过了return Result.fail(用户已经购买过一次);}// 6.扣减库存boolean success seckillVoucherService.update().setSql(stock stock - 1) // set stock stock - 1.eq(voucher_id, voucherId).gt(stock, 0) // where id ? and stock 0.update();if (!success) {// 扣减失败return Result.fail(库存不足);}// 7.创建订单VoucherOrder voucherOrder new VoucherOrder();// 7.1.订单idlong orderId redisIdWorker.nextId(order);voucherOrder.setId(orderId);// 7.2.用户idvoucherOrder.setUserId(userId);// 7.3.代金券idvoucherOrder.setVoucherId(voucherId);save(voucherOrder);// 7.返回订单idreturn Result.ok(orderId);} }三、事务控制问题 以上代码还是存在问题问题的原因在于当前方法被spring的事务控制如果你在方法内部加锁可能会导致当前方法事务还没有提交但是锁已经释放也会导致问题所以我们选择将当前方法整体包裹起来确保事务不会出现问题 但是以上做法依然有问题因为你调用的方法其实是this.的方式调用的事务想要生效还得利用代理来生效所以这个地方我们需要获得原始的事务对象 来操作事务 Long userId UserHolder.getUser().getId();//创建锁对象SimpleRedisLock simpleRedisLock new SimpleRedisLock(order userId, stringRedisTemplate);//获取锁boolean isLock simpleRedisLock.tryLock(1200);if (!isLock) {//获取锁失败返回错误信息或重试return Result.fail(不允许重复下单);}try {//增加代理对象进行事务的控制IVoucherOrderService proxy (IVoucherOrderService) AopContext.currentProxy();return proxy.createVoucherOrder(voucherId);}finally {simpleRedisLock.unlock();}四、总结 这只是一人一单单机实现的方法因为synchronized锁只能确保在一个jvm中实现锁的互斥如果在集群中有多个jvm那就不能实现互斥锁最终还是会导致并发问题这个问题的解决由集群中的分布式锁解决。
http://www.dnsts.com.cn/news/82007.html

相关文章:

  • 2015网站备案没下来秦皇岛做网站外包
  • 暴雪战网官网乐陵德州seo公司
  • wordpress登录于未登录菜单如何优化基础建站
  • 调查网站怎么做建一个o2o网站
  • 郯城做网站天津网站建设方案策划
  • 1建设网站的重要性襄阳网站建设公司
  • 个人网站示例什么网站可以做简历
  • 织梦网站模板还原的文件在哪里免费的商城小程序
  • 上饶专业的企业网站建设公司某个产品营销推广方案
  • 青岛建站方案应聘工作哪个网站比较好
  • 设计常去的网站全国物流网站有哪些平台
  • 莱芜网站设计建筑模板生产厂家
  • 服务器及网站建设的特点discuz论坛seo设置
  • 企业网站不备案网上购物网站开发的目的
  • 中文域名 怎么做网站深圳网站建设黄浦网络
  • 网站开发seo要求做一元购网站 要多少钱
  • 微信小程序建站wordpress访问量阅读量
  • 亚马逊网站企业如何注册网站
  • 网站开发应该学哪门语言vi设计是品牌设计吗
  • 专做商品折扣的网站电商入门
  • 惠州网站开发公司电话网络工程师是什么专业
  • 昆山公司网站建设电话石家庄云图网站建设
  • 网站制作要用哪些软件有哪些推广普通话的重要意义
  • 做it行业招标网站seo优化诊断工具
  • 江苏公司网站建设公司小程序线上商城
  • 支付宝网站开发文档wordpress最好选择
  • 江西网站建设价位做一个app开发多少钱
  • 什么公司做网站出名海南进出口公司排名
  • 网站优化培训如何利用云服务器进行网站建设
  • 自己做的网站和ie不兼容旅游网站开发建设方案