where('is_rollback', 0) // 选择未回滚的秒杀 ->where('end_at', '<', Carbon::now()->toDateTimeString()) // 选择已过期的秒杀 ->get() // 获取符合条件的秒杀记录 ->map(function (Seckill $seckill) use ($rollbacks) { // 1. 回滚数量到商品 // 2. 设置为过期 $product = $seckill->product()->first(); // 获取与秒杀相关联的商品 // 获取 Redis 中的秒杀数量 $jsonSeckill = Redis::get($seckill->getRedisModelKey()); // 从 Redis 获取秒杀数据 $redisSeckill = json_decode($jsonSeckill, true); // 将 JSON 数据解码为数组 // 获取剩余的秒杀量 $surplus = Redis::llen($seckill->getRedisQueueKey()); // 从 Redis 获取剩余秒杀量 // 恢复剩余的库存量 // 恢复库存数量 if ($redisSeckill['sale_count'] != 0) { // 如果 Redis 中的销售数量不为零 $product->increment('sale_count', $redisSeckill['sale_count']); // 增加商品的销售数量 } if ($surplus != 0) { // 如果剩余秒杀量不为零 $product->increment('count', $surplus); // 增加商品的总库存数量 } // 同步 Redis 数据到数据库中 $seckill->sale_count += $redisSeckill['sale_count']; // 更新秒杀的销售数量 $seckill->rollback_count += $surplus; // 更新秒杀的回滚数量 $seckill->is_rollback = 1; // 标记为已回滚 $seckill->save(); // 保存更新后的秒杀记录 $rollbacks->push($seckill); // 将已回滚的秒杀记录添加到集合中 // 删除掉秒杀数据 $ids = Redis::connection()->keys("seckills:{$seckill->id}:*"); // 获取与秒杀相关的所有 Redis 键 Redis::del($ids); // 删除这些 Redis 键 }); if ($rollbacks->isNotEmpty()) { // 如果有回滚的秒杀记录 createSystemLog('系统回滚秒杀数据', $rollbacks->toArray()); // 记录系统回滚操作的日志 } } }