当前位置:首页 > PHP

php实现乐观锁

2026-03-13 11:17:08PHP

乐观锁的概念

乐观锁是一种并发控制机制,假设多用户并发操作不会产生冲突,只在提交数据时检查是否有冲突。适用于读多写少的场景。

基于版本号的实现

在数据表中增加一个version字段,每次更新时检查版本号是否一致。

php实现乐观锁

// 假设$pdo是已建立的PDO连接
$id = 1;
$newValue = '更新后的值';

// 开启事务
$pdo->beginTransaction();

try {
    // 查询当前数据和版本号
    $stmt = $pdo->prepare("SELECT value, version FROM table WHERE id = ?");
    $stmt->execute([$id]);
    $row = $stmt->fetch(PDO::FETCH_ASSOC);

    $currentVersion = $row['version'];

    // 更新数据,同时检查版本号
    $updateStmt = $pdo->prepare(
        "UPDATE table SET value = ?, version = version + 1 
         WHERE id = ? AND version = ?"
    );
    $updateStmt->execute([$newValue, $id, $currentVersion]);

    // 检查是否更新成功
    if ($updateStmt->rowCount() === 0) {
        throw new Exception("数据已被其他进程修改,请重试");
    }

    // 提交事务
    $pdo->commit();
    echo "更新成功";
} catch (Exception $e) {
    $pdo->rollBack();
    echo "错误: " . $e->getMessage();
}

基于时间戳的实现

使用时间戳字段替代版本号,原理类似但精度更高。

$id = 1;
$newValue = '更新后的值';
$currentTimestamp = time(); // 或从数据库获取

$updateStmt = $pdo->prepare(
    "UPDATE table SET value = ?, last_modified = ? 
     WHERE id = ? AND last_modified = ?"
);
$updateStmt->execute([
    $newValue, 
    $currentTimestamp, 
    $id, 
    $row['last_modified']
]);

CAS(Compare-And-Swap)实现

直接比较原值是否变化,适合简单场景。

php实现乐观锁

$id = 1;
$newValue = '新值';
$oldValue = '原值';

$updateStmt = $pdo->prepare(
    "UPDATE table SET value = ? WHERE id = ? AND value = ?"
);
$updateStmt->execute([$newValue, $id, $oldValue]);

if ($updateStmt->rowCount() === 0) {
    echo "数据已被修改,操作失败";
}

重试机制

乐观锁冲突时应实现重试逻辑。

$maxRetries = 3;
$retryCount = 0;

while ($retryCount < $maxRetries) {
    try {
        // 尝试更新操作
        if (updateWithOptimisticLock()) {
            break;
        }
    } catch (Exception $e) {
        $retryCount++;
        if ($retryCount >= $maxRetries) {
            throw $e;
        }
        usleep(100000); // 等待100ms后重试
    }
}

框架集成示例

Laravel中使用乐观锁:

// 模型需包含version字段
$article = Article::find(1);

// 修改数据
$article->title = '新标题';

try {
    $article->save(); // Laravel会自动处理版本冲突
} catch (\Illuminate\Database\StaleModelLockException $e) {
    // 处理冲突
}

注意事项

  • 乐观锁不解决ABA问题(值被改回原值)
  • 高并发写场景可能产生大量重试
  • 需合理设置重试次数和间隔
  • 事务范围应尽可能小以减少冲突

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

相关文章

php实现文件上传

php实现文件上传

PHP 文件上传实现方法 在 PHP 中实现文件上传需要处理 HTML 表单和服务器端脚本。以下是详细步骤: 创建 HTML 表单 使用 enctype="multipart/form-data"…

php 实现自动收货

php 实现自动收货

PHP 实现自动收货功能 自动收货功能通常用于电商系统,在订单超过一定时间未手动确认收货时自动完成订单。以下是实现方法: 数据库设计 需要订单表包含以下关键字段: CREATE TABLE ord…

php实现mysql

php实现mysql

PHP 连接 MySQL 的基本方法 PHP 提供了多种方式与 MySQL 数据库进行交互,以下是最常用的几种方法。 使用 MySQLi 扩展 MySQLi 是 MySQL 的改进扩展,支持面向对…

php mvc实现

php mvc实现

PHP MVC 实现步骤 模型(Model)层 模型负责数据处理和业务逻辑,通常与数据库交互。创建一个基类模型,其他具体模型继承它。 class Model { protected $db;…

php 线程实现

php 线程实现

PHP 线程实现方法 PHP 本身是单线程语言,但可以通过扩展或库实现多线程功能。以下是几种常见的实现方式: 使用 pthreads 扩展 pthreads 是一个 PHP 扩展,允许在 PHP 中…

php https实现

php https实现

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