当前位置:首页 > 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实现socket

php实现socket

PHP 实现 Socket 通信 PHP 可以通过 socket 扩展实现网络通信,支持 TCP/UDP 协议。以下是实现 Socket 通信的核心步骤和代码示例。 创建 TCP 服务器 // 创建…

php记住密码怎么实现

php记住密码怎么实现

使用Cookie实现记住密码功能 在PHP中,可以通过设置Cookie来记住用户的登录状态。以下是一个简单的实现方式: // 用户登录验证成功后 if ($login_success) {…

php长连接实现

php长连接实现

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

php验证码的实现

php验证码的实现

PHP 验证码实现方法 使用 GD 库生成基础验证码 创建画布并生成随机字符串作为验证码内容: session_start(); $width = 120; $height = 40; $image…

php 实现秒杀

php 实现秒杀

PHP 实现秒杀的关键技术 秒杀系统需要解决高并发、超卖、性能瓶颈等问题。以下是实现秒杀的核心方案: 使用 Redis 预减库存 将商品库存提前加载到 Redis 中,通过原子操作保证库存准确性:…

php搜索功能实现的

php搜索功能实现的

PHP 搜索功能实现方法 数据库搜索实现 使用 SQL 的 LIKE 语句进行模糊匹配,适用于小型网站和简单搜索需求。 $searchTerm = $_GET['search']; $query =…