Redis 实现分布锁

<?php
/**
 * 实现Redis分布锁
 */

$key        = 'test';       //要更新信息的缓存KEY
$lockKey    = 'lock:'.$key; //设置锁KEY
$lockExpire = 10;           //设置锁的有效期为10秒

//获取缓存信息
$result = $redis->get($key);
//判断缓存中是否有数据
if(empty($result))
{
    $status = TRUE;
    while ($status)
    {
        //设置锁值为当前时间戳 + 有效期
        $lockValue = time() + $lockExpire;
        /**
         * 创建锁
         * 试图以$lockKey为key创建一个缓存,value值为当前时间戳
         * 由于setnx()函数只有在不存在当前key的缓存时才会创建成功
         * 所以,用此函数就可以判断当前执行的操作是否已经有其他进程在执行了
         * @var [type]
         */
        $lock = $redis->setnx($lockKey, $lockValue);
        /**
         * 满足两个条件中的一个即可进行操作
         * 1、上面一步创建锁成功;
         * 2、   1)判断锁的值(时间戳)是否小于当前时间    $redis->get()
         *      2)同时给锁设置新值成功    $redis->getset()
         */
        if(!empty($lock) || ($redis->get($lockKey) < time() && $redis->getSet($lockKey, $lockValue) < time() ))
        {
            //给锁设置生存时间
            $redis->expire($lockKey, $lockExpire);
            //******************************
            //此处执行插入、更新缓存操作...
            //******************************

            //以上程序走完删除锁
            //检测锁是否过期,过期锁没必要删除
            if($redis->ttl($lockKey))
                $redis->del($lockKey);
            $status = FALSE;
        }else{
            /**
             * 如果存在有效锁这里做相应处理
             *      等待当前操作完成再执行此次请求
             *      直接返回
             */
            sleep(2);//等待2秒后再尝试执行操作
        }
    }
}
本作品采用《CC 协议》,转载必须注明作者和本文链接
《L01 基础入门》
我们将带你从零开发一个项目并部署到线上,本课程教授 Web 开发中专业、实用的技能,如 Git 工作流、Laravel Mix 前端工作流等。
《L05 电商实战》
从零开发一个电商项目,功能包括电商后台、商品 & SKU 管理、购物车、订单管理、支付宝支付、微信支付、订单退款流程、优惠券等
讨论数量: 2

这个实现有问题,直接看 laravel 的源码

public function acquire()
{
    if ($this->seconds > 0) {
        return $this->redis->set($this->name, $this->owner, 'EX', $this->seconds, 'NX') == true;
    } else {
        return $this->redis->setnx($this->name, $this->owner) === 1;
    }
}
1周前 评论
kakasaber (楼主) 1周前

加个异常处理是不是好点

2周前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!