当前位置: 首页 > news >正文

PHP分布式锁与应用场景

PHP分布式锁与应用场景

分布式锁在多个进程同时操作共享资源时很有用。Redis是实现分布式锁的常用工具。今天说说PHP中分布式锁的实现。

Redis的SET NX实现锁。

```php
class RedisDistributedLock
{
private Redis $redis;
private string $prefix = 'lock:';
private int $defaultTimeout = 10;

public function __construct(Redis $redis)
{
$this->redis = $redis;
}

public function acquire(string $key, int $timeout = null): ?string
{
$timeout = $timeout ?? $this->defaultTimeout;
$lockKey = $this->prefix . $key;
$token = bin2hex(random_bytes(16));

$result = $this->redis->set($lockKey, $token, ['NX', 'EX' => $timeout]);
return $result ? $token : null;
}

public function release(string $key, string $token): bool
{
$lockKey = $this->prefix . $key;

$script = '
if redis.call("GET", KEYS[1]) == ARGV[1] then
return redis.call("DEL", KEYS[1])
else
return 0
end
';

return (bool)$this->redis->eval($script, [$lockKey, $token], 1);
}

public function synchronized(string $key, callable $callback, int $timeout = null): mixed
{
$token = $this->acquire($key, $timeout);
if ($token === null) {
throw new RuntimeException("无法获取锁: $key");
}

try {
return $callback();
} finally {
$this->release($key, $token);
}
}
}

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

try {
$lock->synchronized('order:123', function () {
echo "处理订单123\n";
sleep(1);
});
} catch (RuntimeException $e) {
echo "获取锁失败: {$e->getMessage()}\n";
}
?>

数据库实现乐观锁。

```php
class OptimisticLock
{
private PDO $pdo;

public function __construct(PDO $pdo)
{
$this->pdo = $pdo;
}

public function updateWithLock(int $id, array $data, callable $updateFn): bool
{
$maxAttempts = 3;

for ($i = 0; $i < $maxAttempts; $i++) {
$stmt = $this->pdo->prepare("SELECT * FROM products WHERE id = ?");
$stmt->execute([$id]);
$product = $stmt->fetch();

if (!$product) throw new RuntimeException("商品不存在");

$newData = $updateFn($product);

$stmt = $this->pdo->prepare("
UPDATE products SET stock = ?, version = version + 1
WHERE id = ? AND version = ?
");
$stmt->execute([$newData['stock'], $id, $product['version']]);

if ($stmt->rowCount() > 0) return true;
usleep(100000);
}

throw new RuntimeException("更新失败,数据已被其他进程修改");
}
}
?>

分布式锁的应用场景。

```php
// 防止重复下单
function placeOrder(PDO $pdo, Redis $redis, int $userId, int $productId): void
{
$lockKey = "order:{$userId}:{$productId}";
$lock = new RedisDistributedLock($redis);

$lock->synchronized($lockKey, function () use ($pdo, $userId, $productId) {
$stmt = $pdo->prepare("SELECT COUNT(*) FROM orders WHERE user_id = ? AND product_id = ? AND created_at > DATE_SUB(NOW(), INTERVAL 1 MINUTE)");
$stmt->execute([$userId, $productId]);
if ($stmt->fetchColumn() > 0) {
throw new RuntimeException("请勿重复下单");
}
$pdo->prepare("INSERT INTO orders (user_id, product_id) VALUES (?, ?)")->execute([$userId, $productId]);
});
}

// 定时任务防重复执行
function runUniqueTask(string $taskName, callable $task): void
{
$redis = new Redis();
$redis->connect('127.0.0.1', 6379);
$lock = new RedisDistributedLock($redis);

try {
$lock->synchronized("task:{$taskName}", $task, 3600);
} catch (RuntimeException $e) {
echo "任务已在其他进程执行\n";
}
}
?>

分布式锁在需要互斥访问共享资源的场景中很有用。Redis锁实现简单性能好,但要处理锁超时和释放的问题。乐观锁通过版本号解决冲突,适合读多写少的场景。

http://www.jsqmd.com/news/976615/

相关文章:

  • 任天堂Switch大气层系统终极指南:5个步骤快速上手自定义固件
  • FPGA入门避坑指南:从选型到烧录,我的第一个‘点灯’项目踩了哪些雷?
  • MCU深度学习:从GPIO到通信协议,系统化掌握单片机核心原理与项目实战
  • 2023电赛E题STM32F1嵌入式工程:CAN通信+伺服控制+完整驱动与算法实现
  • 2026石家庄名表回收指南:行情、避坑与四家机构实测 - 奢侈品回收测评
  • 别再死记硬背了!用这5个真实项目案例,帮你彻底搞懂软件工程导论的核心概念
  • 智能会议管理系统/视频直播点播EasyDSS打造一体化应急调度解决方案
  • HC08微控制器SCI串口通信:输入时钟与波特率配置详解
  • Blender超级导入导出插件:用复制粘贴彻底改变你的3D工作流 [特殊字符]
  • PN7160 NFC控制器硬件集成与软件移植实战指南
  • PN5190 NFC评估板从零上手:硬件配置、软件调试与射频优化全攻略
  • 供应链管理核心:从OTDC到OTDD,构建高韧性交付体系
  • 绝区零自动化助手:从日常任务到高阶挑战的完整解决方案
  • 告别XY平面局限:用CloudCompare的‘最佳拟合平面’Delaunay功能,搞定倾斜地形的三维建模
  • PMCE框架:小样本学习中的多粒度语义融合与双向特征增强
  • GNSS软件接收机调试指南:如何用MATLAB的plotTracking.m可视化分析跟踪环路性能
  • 无线通信基石:从CDMA到5G,硬判决Viterbi译码为何仍是经典?
  • 南京大学LaTeX论文模板终极指南:快速完成高质量毕业论文排版
  • PyTorch 0.4老版本兼容指南:手把手修复MNIST训练中的Variable弃用等坑(附完整可运行代码)
  • 别再到处找教程了!一份保姆级的SimpleFOC、ODrive、VESC学习路线图(附资源下载)
  • 东莞闲置浪琴、百年灵急变现,行业第一 “禹竞名奢汇” 同城快速上门 - 名奢变现站
  • STM32F4网线热插拔修复记:从同事的遗留Bug到CubeMX 6.3.0 + LWIP的完整解决方案
  • 单文件MATLAB版SGP4轨道解算工具:支持TLE输入、任意时刻外推与时间点插值
  • 如何快速掌握Cocos Creator三消游戏开发:开心消消乐完整实战指南
  • PCL点云库深度解析:除了OpenCV,3D视觉开发者必须掌握的模块与实战配置
  • GPT 智能交互效果与能力边界实测
  • 手把手教你用AI语音合成(Edge-TTS + Python)打造《当红明星》英文剧本有声剧
  • 嵌入式硬件触发同步:TRGMUX原理与NXP K32L2A实战应用
  • D2DX:终极经典游戏现代化工具,让《暗黑破坏神2》在现代PC上完美重生
  • AI大模型API中转聚合平台怎么选?2026高可用稳定靠谱服务商深度横评