一、单机版

模拟秒杀伪代码

  1. $group_id = 21;
  2. $user_id = uniqid();
  3. $lockKey = 'lock:user_id_' . $user_id;
  4. $resultKey = 'res:group_id_' . $group_id;
  5. $info = Redis::get($resultKey);
  6. if (!is_null($info) && $info <= 0) {
  7. return "秒杀结束!";
  8. }
  9. $lock = Redis::set($lockKey, $user_id, 'PX', 10000, 'NX');
  10. if ($lock) {
  11. DB::beginTransaction();
  12. try {
  13. $res = DB::table('group')->where('id', $group_id)->where('days', '>', 0)->decrement('days'); //库存-1
  14. if ($res) {
  15. $info = DB::table('group')->where('id', $group_id)->value('days'); //商品剩余个数
  16. $res = DB::table('notify_log')->insert(['log' => '用户id:' . $user_id . '抢购成功,商品剩余' . $info . '个']); //插入日志(订单)
  17. if ($res) {
  18. Redis::set($resultKey, $info);
  19. //释放锁
  20. $luaScript = <<<EOF
  21. if redis.call("get",KEYS[1]) == ARGV[1]
  22. then
  23. return redis.call("del",KEYS[1])
  24. else
  25. return 0
  26. end
  27. EOF;
  28. $res = Redis::eval($luaScript, 1, $lockKey, $user_id);
  29. }
  30. }
  31. DB::commit();
  32. return '抢购成功!';
  33. } catch (\Exception $exception) {
  34. DB::rollBack();
  35. return '请稍后重试!';
  36. }
  37. }
  38. echo "请稍后重试!";