Redis实现分布式锁 php

<?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秒后再尝试执行操作
        }
    }
}


实现分布式锁用到的Redis命令介绍:

setnx(key, value)

    将key的值设为value,当且仅当key不存在。

    若给定的key已经存在,则SETNX不做任何动作。

    SETNX是”SET if Not eXists”(如果不存在,则SET)的简写。

    返回值:

        设置成功,返回1。

        设置失败,返回0。

 

    get(key)

    返回key所关联的字符串值。

    如果key不存在则返回特殊值nil。

    假如key储存的值不是字符串类型,返回一个错误,因为GET只能用于处理字符串值。

    返回值:

        key的值。

        如果key不存在,返回nil。

 

    getset(key, value)

        将给定key的值设为value,并返回key的旧值。

        当key存在但不是字符串类型时,返回一个错误。

        返回值:

            返回给定key的旧值(old value)。

            当key没有旧值时,返回nil。

 

    expire(key, seconds)

    为给定key设置生存时间。

    当key过期时,它会被自动删除。

    在Redis中,带有生存时间的key被称作“易失的”(volatile)。

    在低于2.1.3版本的Redis中,已存在的生存时间不可覆盖。

    从2.1.3版本开始,key的生存时间可以被更新,也可以被PERSIST命令移除。(详情参见 http://redis.io/topics/expire)。

    返回值:

        设置成功返回1。

        当key不存在或者不能为key设置生存时间时(比如在低于2.1.3中你尝试更新key的生存时间),返回0。

 

    ttl(key)

    返回给定key的剩余生存时间(time to live)(以秒为单位)。

    返回值:

        key的剩余生存时间(以秒为单位)。

        当key不存在或没有设置生存时间时,返回-1 。

 

    del(key)

    移除给定的一个或多个key。

    返回值:

        被移除key的数量。


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值