PHP抽奖活动加内存锁,原理是什么?

发布于 2017-05-06 01:53:30 字数 2015 浏览 1279 评论 1

PHP抽奖活动加内存锁,原理是什么?如何实现?

    public function acquire($key) {
        //如果需要同时获取两个锁
        if ( is_array($key) && count($key) == 2 ) {
            while (TRUE) {
                $res = array();
                foreach($key as $k => $v) {
                    $res[$k] = $this->acquire($v);
                    if ( !$res[$k] ) {
                        break;
                    }
                }
                //若第一个锁未拿到则直接返回
                if ( !$res[0] ) {
                    $err = new SysErr(System::MEMCACHE_ACQUIRE_LOCK_ERROR);
                    ErrorHandle::throwErr($err);
                } elseif( !$res[1] ) {
                    //释放第一个锁,等待然后重试
                    $this->release($key[0]);
                    usleep(LockConfig::LOCK_TIMEWAIT);
                } else {
                    return TRUE;
                }
            }
        } else {
            $lock_key = LockConfig::LOCK_PREFIX . $key;
            $i = 0;
            do {
                $lock = $this->_memcache->add( $lock_key, 1, LockConfig::LOCK_TIMEOUT );
                //如果第一次没有获取到锁则等待指定时间后重试
                if ($i > 0) {
                    usleep(LockConfig::LOCK_TIMEWAIT);
                }
                $i++;
                //超过重试次数后退出
                if ($i > LockConfig::LOCK_RETRY_TIMES) {
                    $err = new SysErr(System::MEMCACHE_ACQUIRE_LOCK_ERROR);
                    ErrorHandle::throwErr($err);
                }
            } while( !$lock );

            // 记录log
            if ($i > 1) {
                LogHelper::warning('lock.log', "Acquire lock '{$lock_key}' for {$i} times");
            }
            return $lock;
        }
    }
    
    
      /**
     * 释放内存锁
     *
     * @param  string $key 内存锁去除前缀后的key值
     * @return bool        释放成功返回TRUE
     */
    public function release($key) {
        $lock_key = LockConfig::LOCK_PREFIX . $key;
        return $this->_memcache->delete($lock_key);
    }

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

瑾兮 2017-05-06 01:53:30

抽奖用不到内存锁吧。用个Redis队列或者事务加Mysql的锁应该可以了吧。。
你要的内存锁不知道是不是这个:$lock = new CacheLock('key_name'); $lock->lock(); //logic here $lock->unlock(); CacheLock 进程锁,主要用来进行cache失效时的单进程cache获取,防止过多的SQL请求穿透到数据库 用于解决PHP在并发时候的锁控制,通过文件/eaccelerator进行进程间锁定 如果没有使用eaccelerator则进行进行文件锁处理,会做对应目录下产生对应粒度的锁 使用了eaccelerator则在内存中处理,性能相对较高 不同的锁之间并行执行,类似mysql innodb的行级锁

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文