首页 > 代码库 > 基于redis的分布式锁

基于redis的分布式锁

 

<?php/** * 基于redis的分布式锁 * * 参考开源代码: * http://nleach.com/post/31299575840/redis-mutex-in-php * * https://gist.github.com/nickyleach/3694555 */pc_base::load_sys_class(‘cache_redis‘, ‘‘, 0);class dist_key_redis {    //锁的超时时间    const TIMEOUT = 20;    const SLEEP = 100000;    /**     * Stores the expire time of the currently held lock     * 当前锁的过期时间     * @var int     */    protected static $expire;    public static function getRedis()    {        return new cache_redis();    }    /**     * Gets a lock or waits for it to become available     * 获得锁,如果锁被占用,阻塞,直到获得锁或者超时     *     * 如果$timeout参数为0,则立即返回锁。     *      * @param  string    $key             * @param  int        $timeout    Time to wait for the key (seconds)     * @return boolean    成功,true;失败,false     */    public static function lock($key, $timeout = null){        if(!$key)        {            return false;        }         $start = time();        $redis = self::getRedis();         do{            self::$expire = self::timeout();                        if($acquired = ($redis->setnx("Lock:{$key}", self::$expire)))            {                break;            }            if($acquired = (self::recover($key)))            {                break;            }            if($timeout === 0)             {                //如果超时时间为0,即为                break;            }             usleep(self::SLEEP);        } while(!is_numeric($timeout) || time() < $start + $timeout);         if(!$acquired)        {            //超时            return false;        }         return true;    }     /**     * Releases the lock     * 释放锁     * @param  mixed    $key    Item to lock     * @throws LockException If the key is invalid     */    public static function release($key){        if(!$key)        {            return false;        }        $redis = self::getRedis();         // Only release the lock if it hasn‘t expired        if(self::$expire > time())         {            $redis->del("Lock:{$key}");        }    }     /**     * Generates an expire time based on the current time     * @return int    timeout     */    protected static function timeout(){        return (int) (time() + self::TIMEOUT + 1);    }     /**     * Recover an abandoned lock     * @param  mixed    $key    Item to lock     * @return bool    Was the lock acquired?     */    protected static function recover($key){        $redis = self::getRedis();        if(($lockTimeout = $redis->get("Lock:{$key}")) > time())        {            //锁还没有过期            return false;        }         $timeout = self::timeout();        $currentTimeout = $redis->getset("Lock:{$key}", $timeout);         if($currentTimeout != $lockTimeout)        {            return false;        }         self::$expire = $timeout;        return true;    }}?>

 

基于redis的分布式锁