php抢购商品redis高并发

  • 抢购

主要针对两个问题
一、高并发对数据库产生的压力
二、竞争状态下如何解决库存的正确减少("超卖"问题)

解决
第一个问题,对于PHP来说很简单,用缓存技术就可以缓解数据库压力,比如memcache,redis等缓存技术。

代码参考

// 关闭自动提交
$this->db_conn->autocommit(FALSE);//开启事务

//获取商品库存
$query_sql = 'select stock from goods where id ='.$goods_id .' lock in share mode'; //加mysql共享锁[提交前不允许其他事务修改]

$stock = $this->query($query_sql);
if ($stock < $num) {
	return $this->log('库存不足_'.$stock);
}

//减库存

//创订单

//提交事务

REDIS

以商品id生成key,redis获取库存,开启redis监控key和redis事务首次获取失败: 数据查询商品库存存入redis'

    /**
     * 生成商品库存redis
     */
    public function redis()
    {
        $data = [
            ['id' => 1,'stock' => 2],
            ['id' => 2,'stock' => 23],
            ['id' => 3,'stock' => 1]
        ];

        foreach ($data as $v) {
            $redis_key = 'goods_id_' . $v['id'];
            for ($i = 0; $i < $v['stock']; $i++) {
                //插入redis中商品的表抢购时从这读取
                $this->redis->lPush($redis_key, 1);
            }
        }
        $this->success('生产库存成功');
    }

    /**
     * 抢购
     */
    public function skill()
    {
        $data = input();
        //模拟随机用户id
        $uid = rand(10000,99999);
        //传商品id
        $redis_key = 'goods_id_' .  $data['id'];
        //查询redis中商品的数量长度
        $len = $this->redis->lLen($redis_key);
        $str = "";
        if(!$len || $len<=0){
            $str .= $uid."抢购失败,商品售罄";
        }else{
            $redis_user_name = "goods_id_".$data['id']."_uid";
            //判断已抢购列表中是否已存在该用户,获取列表中所有的数据
            $skill_user_list = $this->redis->lrange($redis_user_name, 0, -1);
            if(in_array($uid, $skill_user_list)){
                $str .= $uid."已经抢购成功";
            }else{
                //从redis商品表中取出一个
                $this->redis->rPop($redis_key);
                //插入用户抢购成功的redis表中
                $this->redis->lPush($redis_user_name,$uid."_".microtime().rand(10000,99999));
                $str .= $uid."抢购成功";
            }
        }
        //存日志信息与流程无关
        $path = __DIR__ . "/../../../redis_log.txt";
        $file = fopen($path, "a+");        //创建文件或打开文件
        fwrite($file, '抢购信息' . '----' . $str . '-------------------' . '时间:' . date('Y-m-d H:i:s', time()) . "\r\n");
        echo '完成';
    }

你可能感兴趣的:(php,redis,redis,php)