当前位置:首页 > PHP

php实现抢购

2026-02-13 22:41:16PHP

PHP实现抢购功能

抢购功能需要处理高并发请求,确保数据的准确性和系统的稳定性。以下是实现抢购功能的关键步骤:

数据库设计 创建商品表和订单表,商品表需包含库存字段,订单表记录抢购成功的用户信息。使用事务和锁机制保证数据一致性。

CREATE TABLE `product` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(100) NOT NULL,
  `stock` int(11) NOT NULL,
  PRIMARY KEY (`id`)
);

CREATE TABLE `order` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `product_id` int(11) NOT NULL,
  `user_id` int(11) NOT NULL,
  `create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
  PRIMARY KEY (`id`)
);

悲观锁实现 在查询商品库存时使用SELECT FOR UPDATE锁定记录,防止其他进程同时修改。

$pdo->beginTransaction();
try {
    $stmt = $pdo->prepare("SELECT stock FROM product WHERE id = ? FOR UPDATE");
    $stmt->execute([$productId]);
    $product = $stmt->fetch();

    if ($product['stock'] > 0) {
        $pdo->prepare("UPDATE product SET stock = stock - 1 WHERE id = ?")->execute([$productId]);
        $pdo->prepare("INSERT INTO `order` (product_id, user_id) VALUES (?, ?)")->execute([$productId, $userId]);
        $pdo->commit();
        echo "抢购成功";
    } else {
        $pdo->rollBack();
        echo "库存不足";
    }
} catch (Exception $e) {
    $pdo->rollBack();
    echo "系统繁忙";
}

Redis缓存和队列 使用Redis原子操作减轻数据库压力,先将请求放入队列再异步处理。

$redis = new Redis();
$redis->connect('127.0.0.1', 6379);

// 检查库存
$stock = $redis->get("product_stock_{$productId}");
if ($stock <= 0) {
    echo "已售罄";
    exit;
}

// 原子减库存
$remain = $redis->decr("product_stock_{$productId}");
if ($remain >= 0) {
    // 将订单信息放入队列
    $orderData = json_encode(['product_id' => $productId, 'user_id' => $userId]);
    $redis->lPush('order_queue', $orderData);
    echo "抢购成功";
} else {
    $redis->incr("product_stock_{$productId}"); // 恢复库存
    echo "库存不足";
}

限流措施 使用Redis实现计数器限流,防止系统过载。

$key = "user_request_{$userId}";
$limit = 5; // 每秒限制5次请求

if ($redis->incr($key) > $limit) {
    echo "请求过于频繁";
    exit;
}
$redis->expire($key, 1); // 1秒过期

静态化页面 将商品详情页生成静态HTML,减少服务器动态请求压力。使用Nginx直接返回静态文件。

分布式锁 在集群环境下使用Redis实现分布式锁,确保同一时间只有一个进程处理库存扣减。

$lockKey = "product_lock_{$productId}";
$randomValue = uniqid();
$locked = $redis->set($lockKey, $randomValue, ['NX', 'EX' => 10]);

if ($locked) {
    try {
        // 处理抢购逻辑
    } finally {
        // 确保释放自己的锁
        if ($redis->get($lockKey) == $randomValue) {
            $redis->del($lockKey);
        }
    }
} else {
    echo "系统繁忙";
}

异步处理 使用消息队列将订单处理与抢购请求分离,提高响应速度。RabbitMQ或Kafka都是可选方案。

库存预热 活动开始前将库存加载到Redis,避免直接查询数据库。定时同步Redis和数据库的库存数据。

php实现抢购

验证码机制 在抢购前增加图形验证码或短信验证码,防止机器人刷单。

标签: php
分享给朋友:

相关文章

php实现树

php实现树

PHP实现树结构的方法 在PHP中实现树结构通常可以通过递归或迭代的方式完成。以下是几种常见的实现方法: 递归实现树结构 递归是处理树结构的自然方式,尤其适用于具有未知深度的树。 class Tr…

php 实现文件下载

php 实现文件下载

实现文件下载的基本方法 使用 PHP 实现文件下载的核心是通过设置 HTTP 头部信息,强制浏览器将文件作为附件下载而非直接显示。以下是一个基础实现示例: $file_path = '/path/t…

php实现聊天

php实现聊天

实现 PHP 聊天功能的方法 使用 WebSocket 和 PHP 实现实时聊天 WebSocket 是一种全双工通信协议,适合实现实时聊天功能。PHP 可以通过 Ratchet 库实现 WebSo…

php 实现排序

php 实现排序

PHP 实现数组排序的方法 PHP 提供了多种内置函数和方法来实现数组排序,适用于不同的排序需求。以下是一些常见的排序实现方式: 使用 sort() 函数对数组进行升序排序 sort() 函数对数组…

php实现下载

php实现下载

PHP实现文件下载 使用PHP实现文件下载可以通过设置HTTP头部信息强制浏览器下载文件而非直接打开。以下是几种常见的方法: 方法一:直接输出文件内容 $file_path = 'path/to/…

php实现秒杀

php实现秒杀

PHP实现秒杀功能的关键技术 秒杀系统需要解决高并发、数据一致性、系统稳定性等问题。以下是PHP实现秒杀功能的核心技术方案: 数据库优化 使用InnoDB引擎的行级锁和事务特性,确保数据一致性。商品…