在实际应用中,例如抽奖,当同时间有N个用户一起抽奖时,同时访问数据库,如果不做处理,可能出现同一个奖品被多人抽中的情况,或者在秒杀抢购时,N个用户一起抢,可能出现超卖现象,这里介绍用redis来防止以上的情况
一、首先在宝塔中,安装redis软件,并且在自己项目对应的php版本中,开通redis插件
二、处理抽奖中,防多用户抽到同一个奖tp5处理办法
$redis = new \Redis();
$redis->connect('127.0.0.1', 6379,2);// 127.0.0.1 连接的IP,6379 连接的端口,2 连接的超时时长,单位:秒
$is_lock=$redis->setnx($userData['weichat_openid'],time()+30);
if(!$is_lock){
$lock_time=$redis->get($userData['weichat_openid']);
//锁已过期,重置
if($lock_time<time()){
$redis->del($userData['weichat_openid']);
$is_lock=$redis->setnx($userData['weichat_openid'],time()+30);
}
}
if($is_lock){
//数据有效,处理逻辑
//..............
//处理完后,解锁
$redis->del($userData['weichat_openid']);
}else{
sleep(1);
}
三、处理秒杀,抢购出现超卖现象
$redis = new \Redis();//创建redis对象
$redis->connect('127.0.0.1', 6379,2);// 127.0.0.1 连接的IP,6379 连接的端口,2 连接的超时时长,单位:秒
$redis_name = 'oa'.$hdData['id'];//创建一个独立的name
for ($i=0;$i<=$maxNum;$i++){//for循环,要秒杀或抢购的数量,用$redis->lPush到redis中
$redis->lPush($redis_name,$i);
}
//通过上面方法,通过redis保存好要秒杀或抢购的数里,在用户进行秒杀时,进行下面的处理
$redis_name = 'oa'.$data['id'];
$num = $redis->lPop($redis_name); //弹出并获取第一个元素
if (!$num){ //判断是否有值 没值就代表商品已经卖完了
$redis->close();
return json('报名人数已满');//如果没有数里,就直接返回
}
//如果没有返回,表示还有数量名额,可以继续下面的逻辑处理