秒杀库存控制

您所在的位置:网站首页 redis常见错误 秒杀库存控制

秒杀库存控制

2023-06-19 00:18| 来源: 网络整理| 查看: 265

业务场景

对某个套餐或产品进行销售,设置待销售品总数量。销售时不能出现超卖情况,即销售品剩余数量不能为负数。

业务需求 系统高并发,极端热门套餐抢购比率只有1%,比如100个销售品在几秒内抢购完,在前端库存判断需要支持上10w的库存快速判断 商品不能出现超售情况 多个商户进行销售,保证剩余商品数量的数据一致性 需求分析 获取商品剩余数量进行条件判断和更新数据操作,是两个独立的操作,中间有可能有其他应用修改数据从而产生冲突。在冲突的发生时,用户需要合并最新的数据,再进行条件判断和数据修改。将两个独立操作封装成一个原子的服务,保证(剩余数量-销售量)之后,商品剩余量不为负数; 缓存提供了返回版本号的vget的操作和带版本号的数据减操作vdecrBy. 示例方案 方案1:先支持有超卖风险的原子事务操作 //没有冲突的减库存原子函数,在执行库存判断 public boolean decreaseFunction2(String key,long value, Jedis jedis,int retreyNumber){ Long remain = jedis.decrBy( key, 1); return remain.longValue() > 0; } 方案2:使用乐观锁客户端的乐观锁机制实现

注:完整缓存API使用代码可以参考并发修改冲突示例,本示例在于说明乐观锁的使用场景,在复杂的业务对象list,map等并发修改时更适用。

//没有冲突的减库存原子函数 public boolean decreaseFunction(String key,long value, VProxyJedis vjedis,int retreyNumber){ boolean flag = false; //在扣除操作失败时,进行重试,重试次数为retreyNumber while ( (!flag) && (retreyNumber>0) ){ try{ //原子操作1:通过vget得到当前key对应value的值和版本号 VersionResult result = vjedis.vget( key); //判断剩余商品数量是否充足 if((Long.parseLong(result.getValue())-value)>=0){ //操作1 和操作2 之间可能有其他应用修改数据产生状态不一致 //原子操作2:商品剩余量-销售量,基于当前条件判断的版本号去更新 vjedis.vdecrBy( key, value, result.getVersoion()); } //商品剩余数量扣除成功 , 设置操作成功标志flag = true flag = true; }catch(Exception e){ //如果有其他进程修改了数据,会引发版本号冲突,错误码:ErrorMessage_DiffVerison if(e.getMessage().equals(ErrorMessage_DiffVerison)){ flag = false; //设置操作是否成功标志flag=false, retreyNumber--;//减去一次重试次数,通过while循环再进行操作 } } } return flag; }


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3