小程序商品库存及限购优化改造
1、商品库存
1.1、修改商品库存
新建、更新商品时,更新Redis剩余库存数量
- macan/spu/save 商品发布
macan/spu/update 商品更新
删除商品时,删除Redis剩余库存数量
- macan/spu/del/{pkId} 商品删除
更新商品库存数据表之后更新缓存(需加redis锁)
场景
- 库存从 大->小
库存从 小->大
库存从不限->限库存
库存从限库存->不限库存
redis剩余库存键值对定义
- 键 prado:goodsStockResidue:${spuId}
值 剩余库存
数据量:3101****条数据
Redis不限库存键值对定义???
- 数据量:2288219条数据
商品总数:2291317 (2百万)
不限库存商品数: 2288219
限库存商品数: 3101
1.1.1、新建商品,初始化Redis剩余库存
- 新建商品,无需加锁
1.1.2、更新商品,更新Redis剩余库存
更新商品,需要加锁,避免同时更新商品库存剩余数量,Rediss缓存问题
- key prado:goodsStockResidueLockPrefix:${spuId}
1.1.2、删除商品,删除Redis剩余库存
1.2、查询商品剩余库存
获取redis中商品的剩余库存
- key prado:goodsStockResidue:${groupId}:${spuId}
如果数据不存在,加锁,避免同时有商品更新逻辑处理
- key prado:goodsStockResidueLockPrefix:${groupId}:${spuId}
根据spuId查询goodsStock,获取表中库存数量与剩余数量
如果商品不限库存
- 设置redis剩余库存值为-1
如果商品限库存
- 计算库存变化差值
increase redis剩余库存
1.3、商品下单前,占用库存
校验订单是否存在“占用”库存操作流水
- 如果存在,则处理过,无需再次处理
对订单id加“占用”Redis锁
- 解决同一个订单并发占用库存请求问题
再次校验订单是否存在“占用”库存操作流水
- 避免在加锁的时,另外的线程产生数据
获取商品的剩余库存GoodsStockResidueCacheBizReadService.queryGoodsStockResidueFromCache
扣减redis商品剩余库存
开启事务,批量更新商品库存表、批量插入库存操作流水表,提交事务
- 如果出现异常,回滚事务,并恢复redis商品剩余库存
异步回写材料销售标志
1.4、商品订单取消支付后,释放库存
根据订单id查询是否存在“确认”库存操作流水
- 如果存在,则表明次订单已经付款结束
根据订单id查询是否存在“释放”库存操作流水
- 如果存在,则处理过释放库存操作,无需再次处理
对订单id加上“释放-确认”Redis锁,解决同一个订单,并发释放、确认库存问题
- key goodsStockReleaseConfirmLockPrefix:${orderId}
再次根据订单id查询是否存在“确认”库存操作流水
再次根据订单id查询是否存在“释放”库存操作流水
根据订单id查询“占用”库存操作流水
循环所有商品,查询redis中的剩余库存数量(防止数据未初始化)
开启事务
批量更新数据库中的商品库存、批量插入释放库存操作流水
增加Redis中商品库存剩余数量
提交事务
如果出现异常,事务会滚,并恢复redis库存剩余数量
异步回写材料销售标志
1.5、商品订单支付成功后,确认库存
根据订单id查询是否存在“释放”库存操作流水
- 如果存在,则表明次订单已经取消订单
根据订单id查询是否存在“确认”库存操作流水
- 如果存在,则处理过确认过库存操作,无需再次处理
对订单id加上“释放-确认”Redis锁,解决同一个订单,并发释放、确认库存问题
根据订单id查询是否存在“释放”库存操作流水
根据订单id查询是否存在“确认”库存操作流水
根据订单id查询“占用”库存操作流水
开启事务,批量插入确认库存操作流水,提交事务
批量增加商品销量
如果发现有库存为0的商品,做售罄下架操作
2、商品限购
2.1、商品下单前,校验商品限购
查询数据库中商品限购数量
- 因为商品下架后,才能修改商品限购数量,所以下单时,限购数量不会发生改变
判断商品是否限购,如果不限购,直接跳过校验
如果商品限购,查询查询goods_sell_log表(库存流水表)
- 锁定库存总数=释放库存总数+确认库存总数+当前锁定库存数
当前用户已下单(包括已支付和未支付)商品数量 = 确认库存总数+当前锁定库存数 =锁定库存总数-释放库存总数
判断当前用户已下单商品数是否达到商品限购数