关于队列的用法,队列里的多个任务的执行顺序是并行的吗?

比如秒杀活动,下单后往队列里放发货的任务,任务的内容是查看库存是否充足,如果大于订单商品数量就发货,否则就不发货并且更新订单状态。

那当队列执行的时候,是一个个的顺序执行发货任务吗?还是同步执行?

队列驱动用的 Redis,直接在 Listener 中实现 ShouldQueue 接口来实现的,但刚刚自己测试了一下,库存没有验证住,大并发的时候回出现超发的情况。

《L03 构架 API 服务器》
你将学到如 RESTFul 设计风格、PostMan 的使用、OAuth 流程,JWT 概念及使用 和 API 开发相关的进阶知识。
《G01 Go 实战入门》
从零开始带你一步步开发一个 Go 博客项目,让你在最短的时间内学会使用 Go 进行编码。项目结构很大程度上参考了 Laravel。
最佳答案

关于库存的处理,我一般都是在接口同步判断,不会下沉到队列里判断。但是如果坚持下沉到队列判断估计也可以(然而并没有条件试验),有以下两种方案:

  1. 查询库存时,使用形如以下语句查询:
    select exists(
    select * from `库存表` where `item_sku_id` = 1 and `已出货` < `库存总量`  for update
    )
    这种方法原理无他,就是利用for update告诉数据库:要拿到排它锁再查询数据
  2. 利用Redis单线程IO的特性,将各SKU对应的库存缓存到Redis,每一次处理订单时先在Redis自减库存,自减后再查一次是否为负数,如果是的话就直接返回订单失败就是。
3年前 评论
24K大白羊 (楼主) 3年前
24K大白羊 (楼主) 3年前
讨论数量: 5

这个是看你开了几个进程了,如果是一个进程 就是串行排队

3年前 评论
24K大白羊 (楼主) 3年前

楼上正解

3年前 评论
24K大白羊 (楼主) 3年前

redis是单线程 但是

任务的内容是查看库存是否充足

高并发不加锁的话 这里会出现问题

3年前 评论
24K大白羊 (楼主) 3年前

关于库存的处理,我一般都是在接口同步判断,不会下沉到队列里判断。但是如果坚持下沉到队列判断估计也可以(然而并没有条件试验),有以下两种方案:

  1. 查询库存时,使用形如以下语句查询:
    select exists(
    select * from `库存表` where `item_sku_id` = 1 and `已出货` < `库存总量`  for update
    )
    这种方法原理无他,就是利用for update告诉数据库:要拿到排它锁再查询数据
  2. 利用Redis单线程IO的特性,将各SKU对应的库存缓存到Redis,每一次处理订单时先在Redis自减库存,自减后再查一次是否为负数,如果是的话就直接返回订单失败就是。
3年前 评论
24K大白羊 (楼主) 3年前
24K大白羊 (楼主) 3年前

@Tsukasa_Kanzaki @CRAYON

感谢二位的分析,之前确实大意了,错误理解了队列的作用,以为只要把任务放到队列里就可以顺序执行了。

那每次抢到红包后就把用户ID 放到 Redis 中,然后每次发之前用 Redis 判断是否存在,这段代码放到队列里是否可以呢?还是一定要放到外面比较好。

任务一 在 Cache::has() 的时候,任务二 也执行到这了,会有并发的问题吗?

3年前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!