一、什么是超卖现象?

  • 有多个线程请求过来后并且都执行成功了,生成了多个订单,并且生成订单所需要的库存大于已有的库存,导致库存少于0,这就是超卖

二、如何解决超卖问题? 库存

day05-点餐平台-购物车、下单 - 图1

  • 通过分布式锁和原子长整型来保证库存一致性,reids和mysql的库存修改必须同时成功,否则全部回滚先去redis
  • 预扣库存先到Redis中预扣库存,预扣成功,证明有库存,正常销售,更新数据库的库存。预扣失败也就是库存数少于0,证明库存不足,无法销售菜品
  • 预扣库存能够解决超卖和服务器并发性能问题

三、整个购物车操作的流程是什么?

image-20210703164824371.png

  1. app端发起请求后
  2. 获得菜品加锁,获得订单加锁,并且它们之间加一把联锁
  3. 查询是否获得到锁
  4. 操作购物车订单项
  5. 如果是 ADD 添加到购物车订单项
    1. 如果库存够,先去redis减库存,再去mysql菜品表库存减少
    2. 查询redis缓存的购物车订单项
    3. 判断之前的购物车订单中是否有此菜品
      1. 如果没有的话则新增
      2. 如果有的话,则进行购物车订单项数量递增
    4. 如果redis库存不足做归还库存操作
  6. 如果是 REMOVE 移除购物车订单项
    1. 先去mysql菜品表增加库存,增加成功后再去查询redis缓存的购物车订单项
    2. 判断购物车订单项存在
      1. 如果购物车订单项的数量大于1,修改当前数量
      2. 如果购物车订单项的数量等于1,则删除此订单项
    3. 去增加redis菜品的库存
  7. 查询当前订单信息,并且处理订单项

四、什么是联锁?

多个线程之间的锁关联起来,把他们组合成一个新对象

五、添加购物车为什么需要添加 菜品和订单 加联锁?

  • 菜品加锁是为了保证库存超卖
  • 订单加锁是防止加菜的订单同时被结算
  • 而它们之间加联锁是为了要保证数据安全,保证菜品库存和订单都没有其他线程在修改

六、添加和移除购物车 如何保证库存的一致性?(MySQL和Redis双写一致性问题)

七、下单操作业务流程是什么?

day05-点餐平台-购物车、下单 - 图3 1、锁定订单 2、查询可以核算订单项 2.1、处理空集合,如果是空集合就创建一个新集合 3、查询购物车订单项 4、购物车订单项不为空才合并 5、执行保存或更新操作 6、重新计算订单金额计算 7、更新订单金额信息 8、清理redis购物车订单项目 9、释放锁 10、再次最新查询订单数据

八、购物车订单项 和 可核算订单项的合并逻辑?

image.png 有五种逻辑,具体看图

九、下单如何保证库存的一致性?(MySQL和Redis双写一致性问题)

通过分布式锁和原子长整型来保证库存一致性,reids和mysql的库存修改必须同时成功,否则全部回滚