当前位置:首页 > PHP

php实现悲观锁

2026-02-15 18:29:14PHP

悲观锁的基本概念

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

通过MySQL实现悲观锁

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

$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秒),超时后自动回滚:

php实现悲观锁

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

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

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

相关文章

php实现登录

php实现登录

PHP 登录功能实现 数据库连接与用户表创建 创建一个数据库连接文件 db.php,用于管理数据库连接。MySQL 示例代码如下: <?php $host = 'localhost'; $db…

php实现文件的下载

php实现文件的下载

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

php队列的实现

php队列的实现

PHP队列的实现方式 PHP中实现队列功能可以通过多种方式,根据需求选择适合的方案: 使用数组实现基础队列 PHP数组本身支持队列操作,利用array_push和array_shift函数: $q…

php数组实现

php数组实现

PHP 数组的基本实现 PHP 数组是一种非常灵活的数据结构,可以存储多个值,并且支持多种类型的键(整数或字符串)。PHP 数组实际上是有序映射(ordered map),可以看作是列表(vector…

php实现域名

php实现域名

PHP实现域名操作的方法 获取当前域名 使用$_SERVER['HTTP_HOST']可以获取当前访问的域名: $currentDomain = $_SERVER['HTTP_HOST']; ech…

php rsa 实现

php rsa 实现

PHP RSA 加密与解密实现 生成密钥对 使用 openssl_pkey_new 生成 RSA 密钥对,并通过 openssl_pkey_export 导出私钥。公钥可从密钥对中提取。 $conf…