zoukankan      html  css  js  c++  java
  • 基于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;
        }
    }
    
    ?>
  • 相关阅读:
    SSM中 web.xml配置文件
    实现网站的登陆,注册,查看商品详细信息,加入购物车,注销登陆等简单功能。
    操作步骤
    mysql 查询 练习题及答案
    水仙花数!
    Spark SQL(4)-Unresolved Plan到Analyzed Plan
    Spark SQL(3) Parser到Unresolved LogicPlan
    Spark SQL(2)-InternalRow和TreeNode
    Spark SQL(1)-简述
    logstash output到kafka记录与总结( No entry found for connection 2)
  • 原文地址:https://www.cnblogs.com/siqi/p/3959517.html
Copyright © 2011-2022 走看看