Skip to content

分布式锁开发指南

本文档介绍 DSPlatform 项目中分布式锁的使用方法。

概述

分布式锁用于确保在并发环境下,同一资源在同一时刻只能被一个进程操作。系统支持 Redis(原子操作)和 File(降级处理)两种驱动。

核心组件

KvManager::lock()

提供分布式锁的获取和释放功能:

php
use app\deshang\kv\KvManager;
use app\deshang\kv\keys\LockKeyManager;

// 获取锁
$lockKey = sprintf(LockKeyManager::LOCK_USER_BALANCE_KEY, $user_id);
$lockValue = KvManager::lock()->acquire($lockKey, 10); // 10秒过期

if ($lockValue) {
    try {
        // 业务逻辑
    } finally {
        // 释放锁
        KvManager::lock()->release($lockValue, $lockKey);
    }
}

LockKeyManager

统一管理所有锁键常量:

php
use app\deshang\kv\keys\LockKeyManager;

// 用户余额锁
$lockKey = sprintf(LockKeyManager::LOCK_USER_BALANCE_KEY, $user_id);

// 支付锁
$lockKey = sprintf(LockKeyManager::LOCK_API_TRADE_PAY_KEY, $order_id);

使用示例

基本用法

php
use app\deshang\kv\KvManager;
use app\deshang\kv\keys\LockKeyManager;

$lockKey = sprintf(LockKeyManager::LOCK_USER_BALANCE_KEY, $user_id);
$lockValue = KvManager::lock()->acquire($lockKey, 10);

if ($lockValue === false) {
    throw new SystemException('系统繁忙,请稍后重试');
}

try {
    // 业务逻辑:修改用户余额
    $this->modifyUserBalance($user_id, $amount);
} finally {
    // 确保释放锁
    KvManager::lock()->release($lockValue, $lockKey);
}

完整示例

php
class UserBalanceService
{
    public function modifyUserBalance($user_id, $amount)
    {
        $lockKey = sprintf(LockKeyManager::LOCK_USER_BALANCE_KEY, $user_id);
        $lockValue = KvManager::lock()->acquire($lockKey, 10);
        
        if ($lockValue === false) {
            throw new SystemException('余额更新失败,系统繁忙,请稍后重试');
        }
        
        try {
            // 获取用户信息
            $user = $this->getUserInfo($user_id);
            
            // 检查余额
            if ($user['balance'] + $amount < 0) {
                throw new CommonException('余额不足');
            }
            
            // 更新余额
            $this->updateUserBalance($user_id, $amount);
            
            // 记录日志
            $this->addBalanceLog($user_id, $amount);
        } finally {
            // 释放锁
            KvManager::lock()->release($lockValue, $lockKey);
        }
    }
}

注意事项

  1. 必须使用 try-finally 确保释放锁,避免死锁
  2. 设置合理的过期时间,防止进程异常退出导致锁无法释放
  3. Redis 驱动提供原子操作,File 驱动存在竞态条件,建议生产环境使用 Redis
  4. 锁值必须保存,释放时用于验证锁的所有者

相关链接


最后更新:2024-12-20
维护者:DSPlatform技术团队(德尚网络)

获取帮助

如果您在使用过程中遇到问题,可以通过以下方式获取帮助:

  • 官方网站https://www.csdeshang.com
  • 电话咨询:15364080101(微信同号)
  • QQ咨询:858761000
  • 邮箱咨询:858761000@qq.com
  • 工作时间:工作日 9:00-18:00
  • 微信咨询:扫码添加微信
微信二维码

版权所有 © 2014-至今 德尚网络