当前位置:首页 > PHP

php 实现事务锁

2026-03-13 05:10:54PHP

使用 MySQL 事务与行锁

在 PHP 中实现事务锁通常结合 MySQL 的 InnoDB 引擎事务机制。通过 BEGIN 开启事务,配合 SELECT ... FOR UPDATE 锁定特定行,确保操作原子性。

php 实现事务锁

$pdo = new PDO('mysql:host=localhost;dbname=test', 'username', 'password');
$pdo->beginTransaction();

try {
    // 锁定指定行(假设锁定ID为1的用户账户)
    $stmt = $pdo->prepare("SELECT * FROM accounts WHERE id = 1 FOR UPDATE");
    $stmt->execute();
    $account = $stmt->fetch(PDO::FETCH_ASSOC);

    // 执行更新操作
    $update = $pdo->prepare("UPDATE accounts SET balance = balance - 100 WHERE id = 1");
    $update->execute();

    $pdo->commit(); // 提交事务并释放锁
} catch (Exception $e) {
    $pdo->rollBack(); // 回滚并释放锁
    echo "Error: " . $e->getMessage();
}

使用 Redis 分布式锁

对于分布式系统,可通过 Redis 的 SETNX(或 Redlock 算法)实现跨进程锁:

php 实现事务锁

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

$lockKey = 'account_lock_1';
$token = uniqid();
$expire = 3000; // 毫秒

// 尝试获取锁
$locked = $redis->set($lockKey, $token, ['NX', 'PX' => $expire]);

if ($locked) {
    try {
        // 执行业务逻辑
        // ...
        // 释放锁(需验证token避免误删)
        $script = "
            if redis.call('get', KEYS[1]) == ARGV[1] then
                return redis.call('del', KEYS[1])
            else
                return 0
            end
        ";
        $redis->eval($script, [$lockKey, $token], 1);
    } catch (Exception $e) {
        $redis->del($lockKey); // 简单处理(生产环境建议用Lua脚本)
    }
} else {
    echo "获取锁失败,请重试";
}

文件锁(本地单机场景)

通过 flock 实现进程级文件锁:

$fp = fopen("/tmp/lockfile", "w+");

if (flock($fp, LOCK_EX)) { // 排他锁
    // 临界区操作
    // ...
    flock($fp, LOCK_UN); // 释放锁
} else {
    echo "无法获取锁";
}
fclose($fp);

注意事项

  • 死锁风险:事务锁需设置超时(如 MySQL 的 innodb_lock_wait_timeout
  • 锁粒度:行锁比表锁并发性更高,但需索引支持
  • 分布式一致性:Redis 锁需处理时钟漂移问题,推荐 Redlock 等成熟方案
  • PHP-FPM 场景:确保异常时能正确释放锁(如 register_shutdown_function

标签: 事务php
分享给朋友:

相关文章

php实现购物车

php实现购物车

PHP实现购物车功能 购物车功能是电商网站的核心模块之一,通常涉及商品添加、删除、数量修改和结算等操作。以下是使用PHP实现购物车功能的几种方法。 使用Session存储购物车数据 Session是…

php实现栈

php实现栈

栈的基本概念 栈(Stack)是一种遵循后进先出(LIFO)原则的数据结构。核心操作包括: push:元素入栈。 pop:元素出栈(返回并移除栈顶元素)。 peek:查看栈顶元素…

php长连接实现

php长连接实现

PHP 长连接实现方法 长连接(Keep-Alive)允许客户端与服务器在一次TCP连接中发送和接收多个HTTP请求/响应,减少重复建立连接的开销。以下是PHP中实现长连接的几种方式: 配置HTTP…

php 路由实现

php 路由实现

PHP 路由实现方法 在 PHP 中实现路由功能有多种方式,以下是几种常见的实现方法: 使用原生 PHP 实现 通过解析 URL 并匹配对应的控制器和动作: $request = $_SERVER…

php实现下载

php实现下载

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

php实现注册登录

php实现注册登录

PHP 注册功能实现 创建数据库表(以 MySQL 为例) CREATE TABLE users ( id INT AUTO_INCREMENT PRIMARY KEY, usern…