当前位置:首页 > PHP

php 实现事务锁

2026-03-13 05:10:54PHP

使用 MySQL 事务与行锁

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

$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 算法)实现跨进程锁:

$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 实现进程级文件锁:

php 实现事务锁

$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 可以通过多种方式实现打印功能,具体取决于打印的目标(如打印机、PDF、网页等)和需求(如直接打印、生成打印预览等)。以下是几种常见的实现方式: 使用 JavaSc…

php 登录实现

php 登录实现

PHP 登录实现 PHP 登录功能通常包括用户认证、会话管理和安全性措施。以下是实现 PHP 登录功能的关键步骤。 数据库准备 创建一个用户表存储用户信息,通常包括用户名、密码(加密存储)和其他必要…

php实现分类

php实现分类

PHP实现分类的方法 数据库设计 创建分类表时,通常需要包含id、名称、父级id等字段。父级id用于实现多级分类结构。 CREATE TABLE categories ( id INT AU…

php 实现类

php 实现类

PHP 类的基本实现 在 PHP 中,类通过 class 关键字定义,后跟类名和一对花括号。类名通常遵循大驼峰命名法(如 ClassName)。以下是基本语法: class ClassName {…

php实现注册登录

php实现注册登录

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

php https实现

php https实现

PHP 中实现 HTTPS 的方法 在 PHP 中实现 HTTPS 主要通过配置服务器和编写代码来确保通信的安全性。以下是几种常见的方法: 配置服务器支持 HTTPS 确保服务器已安装 SSL/T…