随机抢占高并发问题

需求:地图上随机位置点亮。

问题:多个用户随机的时候抢占同一个位置

表结构 (a.b.c.d.e 为需要抢占的位置)

CREATE TABLE `fa_seize` (
  `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
  `a` int(11) DEFAULT NULL,
  `b` int(11) DEFAULT NULL,
  `c` int(11) DEFAULT NULL,
  `d` int(11) DEFAULT NULL,
  `e` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=2 DEFAULT CHARSET=latin1 COMMENT='抢占表';

后端

    /* 解决:随机的时候会有多个用户随机到一个位置的可能 */
    public function test_seize(){
        $map_id="";
        //需要抢占的位置
        $m_arr=['a','b','c','d','e'];
        //打乱数组 - 造成随机
        shuffle($m_arr);
        //去更新每一个需要抢占的位置
        foreach ($m_arr as $m){
            //字段初始的值为null
            //加上null判断是为了防止用户更新成自己的id
            //把抢占的位置置为 1 这样别的用户在置 1 的时候会更新失败
            //利用更新失败 避免抢占
            $ret=Db::name("seize")->where(['id'=>1,$m=>null])->update([$m=>1]);
            //影响行数大于0的时候为更新成功
            if($ret>0){
                //把抢占的位置更新为自己的id 这里假设为111
                Db::name("seize")->where('id',1)->update([$m=>111]);
                //返回前端抢占信息
                $map_id=$m;
                //跳出循环
                break;
            }
        }
        //返回给前端
        $map_id = $map_id == "" ?  "已点满": "位置:".$m;
        echo $map_id;
    }

并发结果

屏幕快照 2019-01-22 下午9.04.36.png


可以看到,在同一秒的请求的几个用户,只有在位置为空的时候才可以抢占到。


随机抢占高并发问题


本站如无特别说明即为原创,转而告知:(http://iwonmo.com/archives/1464.html)

标签: php, 高并发

添加新评论