Redis Zrange 命令 - 通过索引区间返回有序集合成指定区间内的成员

通过一个字符创的自增自减操作保证原子性,然后根据返回值来获取指定的数据内容

/**
     * 领取金额
     * @param $coinId
     * @param $coinHashInfo
     * @return mixed
     */
    public function getCoin($coinSn,$coinHashInfo) {
        $key = $coinSn.$coinHashInfo['max_num'];
        $creatInfo = $this->_redis->get($key);
        if ($creatInfo === false) {//没人领取 从0开始第一个领取
            $this->_redis->set($key,0);
            $location = 0;
        } else {
            $location = $this->_redis->incr($key);
        }
        if ($location == $coinHashInfo['max_num']) {//超过最大领取数
            ApiException::throwException(ApiException::COIN_NOT_RECEIVE, '', array(__FUNCTION__.' fail'));
        }
        //获取指定位置的一个元素 从0开始
        $res = $this->_redis->zRange('coin_split_list_'.$coinSn,$location,$location,true);

        if (empty($res)) {
            Core::write( '---message:领取楚币reids没有get到'.',---data:'.json_encode($res),Core::LEVEL_REDIS_ERROR);
            ApiException::throwException(ApiException::COIN_GET_FAIL, '', array(__FUNCTION__.' fail'));
        }
        $value = array_values($res);
        $key = array_keys($res);
        $split_array = explode('_', $key[0]);

        $getInfo = [
            'money' => $split_array[1], //抽到的金额
            'coin_split_id' => $value[0], //对应的拆分id
        ];
        return $getInfo; //返回抽到的金额
    }

问题:上述的get set很容易在高并发的时候出现超发的现象,应该修改成原子操作。

        $key = $coinSn.'_create_num';
        $location = $this->_redis->decr($key);
        if ($location < 0) {
            ApiException::throwException(ApiException::COIN_NOT_RECEIVE, '', array(__FUNCTION__.' fail'));
        }
        $res = $this->_redis->zRange('coin_split_list_'.$coinSn,$location,$location,true);

        if (empty($res)) {
            Core::write( '---message:领取楚币reids没有get到'.',---data:'.json_encode($res),Core::LEVEL_REDIS_ERROR);
            ApiException::throwException(ApiException::COIN_GET_FAIL, '', array(__FUNCTION__.' fail'));
        }
通过原子操作decr保证取到的位置唯一,从而获取唯一的数据

你可能感兴趣的:(Redis Zrange 命令 - 通过索引区间返回有序集合成指定区间内的成员)