当前位置:首页 > PHP

php实现悲观锁

2026-02-15 18:29:14PHP

悲观锁的基本概念

悲观锁假设并发冲突频繁发生,因此在操作数据前先加锁,确保其他事务无法修改数据。适用于写多读少的场景,常见实现方式包括数据库行锁或表锁。

php实现悲观锁

通过MySQL实现悲观锁

使用SELECT ... FOR UPDATE语句锁定查询的行,直到事务结束(提交或回滚)后释放锁。需确保在事务中执行:

php实现悲观锁

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

try {
    // 锁定id=1的行
    $stmt = $pdo->prepare("SELECT * FROM products WHERE id = 1 FOR UPDATE");
    $stmt->execute();
    $product = $stmt->fetch(PDO::FETCH_ASSOC);

    // 更新操作
    $updateStmt = $pdo->prepare("UPDATE products SET stock = stock - 1 WHERE id = 1");
    $updateStmt->execute();

    $pdo->commit();
} catch (Exception $e) {
    $pdo->rollBack();
    echo "Error: " . $e->getMessage();
}

使用文件锁(File Lock)

对于非数据库场景,可通过flock函数实现文件系统级别的悲观锁:

$fp = fopen("lockfile.txt", "w+");

if (flock($fp, LOCK_EX)) { // 获取独占锁
    // 执行需要加锁的代码
    file_put_contents("data.txt", "updated content");

    flock($fp, LOCK_UN); // 释放锁
} else {
    echo "Could not lock the file!";
}

fclose($fp);

注意事项

  • 死锁风险:悲观锁可能导致死锁,需合理设计锁的获取顺序或设置超时时间。
  • 性能影响:长时间持有锁会降低系统吞吐量,建议缩小锁的作用范围和持有时间。
  • 数据库支持:不同数据库对FOR UPDATE的实现可能不同,需检查数据库文档(如MySQL的InnoDB引擎支持行锁)。

锁超时处理

MySQL可通过设置锁等待超时(默认50秒),超时后自动回滚:

SET innodb_lock_wait_timeout = 10; -- 设置超时为10秒

PHP代码中可捕获超时异常并重试或提示用户。

标签: 悲观php
分享给朋友:

相关文章

php实现文件上传

php实现文件上传

文件上传的基本实现 在PHP中实现文件上传需要使用$_FILES超全局数组处理上传的文件数据。表单必须设置enctype="multipart/form-data"属性,并采用POST方法提交。 创…

php实现注册

php实现注册

注册功能实现步骤 数据库准备 创建用户表,包含字段如id、username、password、email等。示例SQL: CREATE TABLE users ( id INT AUTO_I…

php 购物车实现

php 购物车实现

数据库设计 购物车功能通常需要设计数据库表存储商品和用户信息。常见的表包括products(商品表)、users(用户表)和cart(购物车表)。cart表通常包含字段:id(主键)、user_id(…

php实现文件的下载

php实现文件的下载

PHP 实现文件下载的方法 在 PHP 中实现文件下载功能通常需要设置正确的 HTTP 头信息,并输出文件内容。以下是几种常见的实现方式: 使用 header() 函数强制下载 通过设置 Conte…

php实现跳转

php实现跳转

PHP 实现页面跳转的方法 在 PHP 中实现页面跳转有多种方式,以下是常见的几种方法及其适用场景: 使用 header() 函数 通过 header() 函数发送 HTTP 头部信息实现跳转。注意…

php实现下载

php实现下载

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