php高并发解决方案

//本文需要注意的地方

$num = Db::name('bingfa')->where('id',1)->lock(true)->value('num'); //这里我加了lock锁住本次操作,其他操作需要等待本次操作结束后才能操作

SELECT `num` FROM `api_bingfa` WHERE `id` = 1 LIMIT 1 FOR UPDATE //mysql 源代码,for update就是lock

//这个是日志记录以下测试共用

public function insertLog($log){    
      file_put_contents("log.txt",$log."\n", FILE_APPEND);
 }

//高并发测试工具ab,-n 总请求数 -c 每次的请求数 url你的网址

 ab -n 1000 -c 100 -k  url

1.没有加任何操作的情况下,货存为负

 

2.使用事务操作

$id = 1;
Db::startTrans();
$num = Db::name('bingfa')->where('id',1)->lock(true)->value('num');
if($num>0){
	//库存减少  
	$res = Db::name('bingfa')->where('id',1)->setDec('num');  
	if($res){    
		$this->insertLog('库存减少成功'.$id); 
		Db::commit();
	}else{    
		$this->insertLog('库存减少失败');  
	}   
}else{
	$this->insertLog('库存不足');
	Db::rollback();
}
return 'success';

没有出现负数情况,刚好一百个人获取到

3.redis队列操作

//设置总库存
$store=100;
//tp里已经配置好了,直接调用
$redis = new Redis();
//查看队列里以后的货物		
$res = $redis->llen('goods_store');
//需要入队的货物
$count=$store-$res;
for($i=0;$i<$count;$i++){
    $redis->lpush('goods_store',"1");
}


//这里就是用户购买商品出队
$count=$redis->lpop('goods_store');
//出队查看货物是否存在,不存在则无货物
if(!$count){
	$this->insertLog('error:no store redis');
	return;
}
//存在则提取货物
$res = Db::name('bingfa')->where('id',1)->setDec('num');
$this->insertLog('库存减少成功1'); 

没有出现库存负数的情况

以上二种方式都可以解决高并发的问题

你可能感兴趣的:(PHP)