四时宝库

程序员的知识宝库

php 利用redis分布式锁秒杀解决超卖问题

后续还有优化,目前只有大体思路

public function miaosha(){

$uid=uniqid(); //模仿用户id 随机数代替
#redis 连接
$redis =new \Redis();
$redis->connect('127.0.0.1',6379);
try{
    do{
        $list =[];
        $key='test_key';
        $value =uniqid();
        $numkey ='storeid'.'11111';  //商品的Key 用来存商品数量
        $redis->watch($numkey);  //监听商品数量
      #一个用户只能购买一个
        if($redis->hget('www',$uid)){
            return ['msg'=>'不能重复'];
        }
      //加锁
            $is_lock = $redis->set($key,$value,['nx','ex'=>'10']);
            if($is_lock){
                $arr[$key] =$value; //记录当前获取锁的用户
                $stock = $redis->get($numkey); 
                if($stock<=0){//商品数量为0秒杀结束,删除锁
                    if($redis->get($key)==$arr[$key]){
                        $redis->del($key);
                    }
                    return ['msg'=>'结束'];
                }
              #开启事务
                $redis->multi();
                $redis->decr($numkey);
              $redis->hSet('www',$uid,'11111');
                $redis->lPush('list',$uid);
                $redis->exec();
                #提交事务解锁
                if($redis->get($key)==$arr[$key]){
                    $redis->del($key);
                }
                break;
            }else{
              //没有获取锁睡眠重试
                usleep(5000);
            }

        }while(!is_lock);
    return $redis->lLen('list');
    }catch (\Exception $e){
        $redis->discard();//redis 回滚
        return $e->getMessage();

    }







}

发表评论:

控制面板
您好,欢迎到访网站!
  查看权限
网站分类
最新留言
    友情链接