关于库存扣减问题

昨天面试的时候,被面试官问到库存扣减问题。。。估计面试官把我的项目当成秒杀了。。怪我自己没介绍清楚项目,自己挖坑。。。

今天在博客上看了一些关于库存扣减问题,主要还是觉得比较合适的方式就是使用redis分布式锁,这是最简单的方案,但是如果事务过大,会有性能问题.操作不当,会有死锁问题

基于redis setnx的简易分布式锁

如果两个线程同时执行的话会出现超卖问题在这里插入图片描述
所以我们要加个锁
在这里插入图片描述

但这样在并发量很高的时候,是不合适的,所以,可以考虑库存占用
在这里插入图片描述
二、在Redis中扣减库存
InnoDB的行锁特性其实是一把利与弊都同样明显的双刃剑,在保证一致性的同时却降低了可用性,那么究竟应该如何保证大并发更新热点数据不会导致数据库沦为瓶颈,这其实是秒杀、抢购场景下最核心的技术难题之一。可以尝试将热卖商品的库存扣减操作转移至数据库外,由于Redis的读/写能力要远胜过任何类型的关系型数据库,因此在Redis中实现库存扣减将会是一个不错的替代方案,这样一来,数据库中存储的商品库存可以理解为实际库存,而Redis中存储的商品库存则为实时库存。

1.先查询redis中是否有库存信息,如果没有就去数据库查,这样就可以减少访问数据库的次数。

2.获取到后把数值填入redis,以商品id为key,数量为value。

`redisTemplate.opsForValue().setIfAbsent("key", "value");`

3.设置redis对应这个key的超时时间,以防所有商品库存数据都在redis中。

redisTemplate.expire("key", 30000, TimeUnit.MILLISECONDS);

4.比较下单数量的大小,如果够就做后续逻辑。
执行redis客户端的increment,参数为负数,则做减法。因为redis是单线程处理,并且因为increment让key对应的value 减少后返回的是修改后的值。
有的人会不做第一步查询直接减,其实这样不太好,因为当库存为1时,很多做减3,或者减30情况,其实都是不够,这样就白减。
扣减数据库的库存,这个时候就不需要再select查询,直接乐观锁update,把库存字段值减1 。
做完扣库存就在订单系统做下单。
5.释放锁

redisTemplate.delete("key");
发布了7 篇原创文章 · 获赞 0 · 访问量 109

猜你喜欢

转载自blog.csdn.net/qq_43876433/article/details/105116040