Redis原子性问题

在高并发时候 Llen 多人会获取到相同的值 比如秒杀时候 库存10个 通过llen<10来判断。会有超卖。不是说redis有原子性吗?那不应该出现这情况吧?
后来还用lpop 发现这个不会超卖

阅读 5.4k
3 个回答

你是通过lpush添加数据,然后llen<10来判断是否超卖?原子性是对redis命令来说的,并没有说redis多个命令还是原子性啊,redis原子性这个话术本来就有问题。lpop没问题是lpop是获取加移出,你事先把固定数量的货品lpush入队列,根据redis命令串行执行这个特点,lpop当然不会超卖,因为可以pop的数据项是一定的。但是如果你用llen来判断,命令之间是串行执行但不是原子的,例如,llen和lpop由两个实例同时发出,server端先执行llen再执行lpop,那么根据llen的返回做出的决策是有问题的,会导致超卖
所以你没有理解一个本质:命令原子性、redis server执行串行化、多实例client可以并发请求redis

列一个场景:
A 调用 Llen 返回 1
B 调用 Llen 返回 1

B 先扣除并提交
A 也扣除并提交

这种场景就不能避免超卖,因为在取出 长度的时候是原子,但是取出后的操作会继续扣除的。

业务逻辑
  • 判断库存是否足够
  • 库存足够就卖,库存不够就不卖
面临问题

因为高并发的存在,在判断库存足够的时候再去占用,中间可能已经被其他的线程占用了可销库存导致超卖

解决方案

要解决上述问题就要确保判断库存是否足够占用库存的操作必须是原子性的。
因此可以使用lue脚本来实现(不清楚lue脚本的可以百度)
redis会将整个lue脚本作为一个整体执行,中间不会被其他命令插入。

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题