PHP利用flock解决高并发下单库存超卖

顾言
顾言
发布时间:2026-10-14| 2人浏览过
原创

在高并发的电商抢购或秒杀活动中,多线程或多进程同时读取并更新数据库会导致“超卖”现象(库存变为负数)。本文介绍一种基于PHP `flock`函数的轻量级解决方案,通过文件排他锁串行化处理下单请求,在保证数据一致性的同时兼顾系统稳定性。

问题分析:为什么会出现库存超卖?

假设购买商品的完整流程涉及两条主要SQL语句:

  1. sql1: 查询当前商品库存。
  2. sql2: 执行库存扣减操作(如 UPDATE table SET stock = stock - 1)。

在没有并发控制的情况下,若同时有两个用户发起请求且剩余库存仅剩1件:

  • 两个请求同时执行 sql1,查到的库存均大于0。
  • 随后两个请求都成功执行 sql2。
  • 最终结果:库存从1变为-1,产生超卖事故。

解决方案:文件排他锁机制

解决此类并发问题的常见思路包括乐观锁、队列串行化以及原子性SQL判断等。其中,flock 文件锁是一种在单服务器或多个服务器共享存储环境下,控制进程/线程访问代码块的有效手段。

其核心逻辑是:在处理订单前,先尝试获取锁;如果锁定成功,则执行下单逻辑;否则根据策略拒绝请求或等待。

第1步:准备锁文件路径

在脚本目录下创建一个用于同步的信号文件,例如 lock.txt。该文件本身只作为互斥信号,无需维护内容。

第2步:编写阻塞模式下的锁控制逻辑

适用场景:希望请求排队处理,不直接拒绝用户,但用户可能需要较长时间等待结果。

在此模式下,如果锁已被其他进程占用,当前进程将一直等待直到获取到锁。这可能导致大量请求堆积,消耗内存和连接资源,需谨慎使用。

<?php
// 打开锁文件
$fp = fopen("lock.txt", "w+");

// 尝试获取独占锁(阻塞模式),直到获取成功
if (flock($fp, LOCK_EX)) {
    // ===========================
    // 关键代码区域:处理下单业务逻辑
    // 此处应包含生成订单号、写入数据库库存扣减等操作
    // ===========================

    // 业务处理完毕后,释放锁
    flock($fp, LOCK_UN);
}

// 关闭文件句柄
fclose($fp);
?>

第3步:编写非阻塞模式下的锁控制逻辑

适用场景:追求响应速度,如果无法立即获得锁,直接告知用户“系统繁忙”,保护服务器不被瞬时海量请求压垮。

通过在 flock 中增加 LOCK_NB 标志位实现非阻塞。如果返回 false,说明锁被占用,程序跳过业务逻辑直接报错退出。

<?php
$fp = fopen("lock.txt", "w+");

// 尝试获取独占锁,添加 LOCK_NB 实现非阻塞
if (flock($fp, LOCK_EX | LOCK_NB)) {
    // 获取锁成功,执行下单逻辑
    // ... 业务代码 ...
    flock($fp, LOCK_UN);
} else {
    // 获取锁失败,提示用户
    echo "系统繁忙,请稍后再试";
    // 必须关闭句柄,避免资源泄露
}

fclose($fp);
?>

实施要点与风险提示

1. 必须正确释放和关闭资源

在 try-catch 结构或正常的流程结束处,务必调用 flock($fp, LOCK_UN) 释放锁,并在最后调用 fclose($fp)。未正确释放锁会导致后续请求永远无法获取资源,造成服务挂起。

2. 性能考量

flock 本质上是将并发转化为串行。对于极高并发的秒杀场景,单文件的锁竞争会成为瓶颈,建议结合 Redis Lua 脚本或数据库乐观锁实现更复杂的分布式限流。但在中小规模活动或单机部署中,这是一种简单有效的方案。

3. 文件权限检查

确保运行PHP进程的Web服务器用户(如 www-data, apache, nginx)具有对 lock.txt 文件的读写权限,否则 fopen 或 flock 会静默失败或引发警告。

总结

利用PHP的 flock 函数进行文件排他锁,是解决本地进程并发下库存超卖的一种直观且易实现的方案。开发时需区分“阻塞”与“非阻塞”两种模式以匹配业务需求,并严格管理锁的释放,以避免死锁。

以上就是使用PHP flock解决高并发入库导致库存负数的详细内容,更多关于PHP并发优化的资料请关注本站其它相关文章!

相关标签:

免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。

Python 相关产品和应用

全部下载
Selenium

Selenium

4.51.0 · Windows

用于浏览器自动化和 Web 测试的 Python 工具。

scikit-learn

scikit-learn

1.9.1 · Windows

常用 Python 机器学习算法与模型评估工具库。

Black

Black

26.10.1 · Windows

强调一致性的 Python 自动代码格式化工具。

Ruff

Ruff

0.17.1 · macOS

由 Rust 编写的高速 Python 代码检查和格式化工具。

pytest

pytest

9.1.1 · Windows

简洁而强大的 Python 自动化测试框架。

FastAPI

FastAPI

0.146.0 · Windows

高性能 Python API 框架,支持类型提示和自动接口文档。

Flask

Flask

3.1.3 · Windows

轻量灵活的 Python Web 应用框架。

Django

Django

6.1.2 · Windows

成熟的 Python Web 框架,适合构建内容站点和业务系统。

Spyder

Spyder

6.1.7 · Windows

面向科学计算与数据分析的 Python 集成开发环境。

SciPy

SciPy

1.18.1 · Windows

面向科学、工程和技术计算的 Python 算法库。