操作锁(redis)

防止并发

$biz = '发送贵重物品';
$lockId = $this->getLockId($label1, $label2);

//获取锁
$claimLock = CacheUtil::acquireRedLock($biz, $lockId);
if (!$claimLock) {
    //TODO  ....
    var_dump('获取锁失败');
}

try {

    //TODO 业务逻辑 ....

    //TODO 业务条件判断失败 ....
    if (isset($condition1) && $condition1 !== true) {
        // 释放锁
        CacheUtil::releaseLock($this->bizName, $lockId);
       var_dump('业务条件未达标');
        die();
    }
    
    // 释放锁
    CacheUtil::releaseLock($this->bizName, $lockId);
} catch (Exception $e) {
    // 释放锁
    CacheUtil::releaseLock($this->bizName, $lockId);
    throw $e;
}

function getLockId(int $label1, string $label2): string
{
    return sprintf("%d_%s", $label1, $label2);
}

function acquireRedLock(string $prefix, string $id): bool
{
    $lockid = self::buildLockId($prefix, $id);
    $luaScript = <<<SCRIPT
      local sx = redis.call('SETNX',KEYS[1],ARGV[1]);
      if(sx>0)
      then
         redis.call('EXPIRE',KEYS[1],ARGV[2]);
      end
      return sx;
SCRIPT;
    $rdsConn = getRedisConnection($lockid);
    try {
        return h_retry(3, function () use ($lockid, $luaScript, $rdsConn) {
            $callRet = $rdsConn->eval($luaScript, [$lockid, time(), 6], 1);
            if (!$callRet) {
                throw new \Exception('获锁失败');
            }
            return true;
        });
    } catch (\Throwable $e) {

    }
    return false;
}
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容