首頁  >  問答  >  主體

redis - PHP抽獎活動加上記憶體鎖,原理是什麼?

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);
    }
仅有的幸福仅有的幸福2683 天前548

全部回覆(1)我來回復

  • 为情所困

    为情所困2017-05-16 13:11:23

    抽獎用不到內存鎖吧。用個Redis佇列或是事務加Mysql的鎖應該可以了吧。 。

    你要的記憶體鎖定不知道是不是這個:
    $lock = new CacheLock('key_name');
    $lock->lock();
    //logic here
    $lock->unlock();
    CacheLock 進程鎖,主要用來進行cache失效時的單一進程cache獲取,防止過多的SQL請求穿透到資料庫
    用於解決PHP在並發時候的鎖控制,透過檔案/eaccelerator進行進程間鎖定
    如果沒有使用eaccelerator則進行進行檔案鎖定處理,會做對應目錄下產生對應粒度的鎖
    使用了eaccelerator則在記憶體中處理,效能相對較高
    不同的鎖之間並行執行,類似mysql innodb的行級鎖定

    回覆
    0
  • 取消回覆