久久久久久久视色,久久电影免费精品,中文亚洲欧美乱码在线观看,在线免费播放AV片

<center id="vfaef"><input id="vfaef"><table id="vfaef"></table></input></center>

    <p id="vfaef"><kbd id="vfaef"></kbd></p>

    
    
    <pre id="vfaef"><u id="vfaef"></u></pre>

      <thead id="vfaef"><input id="vfaef"></input></thead>

    1. 站長資訊網(wǎng)
      最全最豐富的資訊網(wǎng)站

      php怎樣應(yīng)對高并發(fā)

      高并發(fā)下的數(shù)據(jù)安全

      我們知道在多線程寫入同一個(gè)文件的時(shí)候,會(huì)出現(xiàn)“線程安全”的問題(多個(gè)線程同時(shí)運(yùn)行同一段代碼,如果每次運(yùn)行結(jié)果和單線程運(yùn)行的結(jié)果是一樣的,結(jié)果和預(yù)期相同,就是線程安全的)。

      php怎樣應(yīng)對高并發(fā)

      如果是MySQL數(shù)據(jù)庫,可以使用它自帶的鎖機(jī)制很好的解決問題,但是在大規(guī)模并發(fā)的場景中,是不推薦使用MySQL的。秒殺和搶購的場景中,最關(guān)鍵的問題,就是“超發(fā)”,如果在這方面控制不慎,會(huì)導(dǎo)致實(shí)際產(chǎn)生的訂單比預(yù)售商品還多的問題。

      超發(fā)的原因:(推薦學(xué)習(xí):PHP編程從入門到精通)

      假設(shè)某個(gè)搶購場景中,我們一共只有100個(gè)商品,在最后一刻,我們已經(jīng)消耗了99個(gè)商品,僅剩最后一個(gè)。這個(gè)時(shí)候,系統(tǒng)發(fā)來多個(gè)并發(fā)請求,這批請求讀取到的商品余量都是1個(gè),然后都通過了余量的判斷,最終導(dǎo)致超發(fā)。

      值得注意的是:記得將庫存字段number字段設(shè)為unsigned,當(dāng)庫存為0時(shí),因?yàn)閡nsigned字段不能為負(fù)數(shù),將會(huì)返回false

      優(yōu)化方案

      優(yōu)化1:使用MySQL的事務(wù),鎖住操作的行 BEGIN ; SELECT … FOR UPDATE ; COMMIT ; ROLLBACK

      <?php 	//優(yōu)化方案1:使用MySQL的事務(wù),鎖住操作的行 	include('./mysql.php'); 	function build_order_no(){ 		return date('ymd').substr(implode(NULL, array_map('ord', str_split(substr(uniqid(), 7, 13), 1))), 0, 8); 	} 	//記錄日志 	function insertLog($event,$type=0){ 		global $conn; 		$sql="insert into ih_log(event,type) 		values('$event','$type')"; 		mysqli_query($conn,$sql); 	} 	 	mysqli_query($conn,"BEGIN");  //開始事務(wù) 	$sql="select number from ih_store where goods_id='$goods_id' and sku_id='$sku_id' FOR UPDATE";//此時(shí)這條記錄被鎖住,其它事務(wù)必須等待此次事務(wù)提交后才能執(zhí)行 	$rs=mysqli_query($conn,$sql); 	$row=$rs->fetch_assoc(); 	 	if($row['number']>0){ 		//生成訂單 		$order_sn=build_order_no(); 		$sql="insert into ih_order(order_sn,user_id,goods_id,sku_id,price) 			values('$order_sn','$user_id','$goods_id','$sku_id','$price')"; 		$order_rs=mysqli_query($conn,$sql); 		//庫存減少 		$sql="update ih_store set number=number-{$number} where sku_id='$sku_id'"; 		$store_rs=mysqli_query($conn,$sql); 		if($store_rs){ 		  echo '庫存減少成功'; 			insertLog('庫存減少成功'); 			mysqli_query($conn,"COMMIT");//事務(wù)提交即解鎖 		}else{ 		  echo '庫存減少失敗'; 			insertLog('庫存減少失敗'); 		} 	}else{ 		echo '庫存不夠'; 		insertLog('庫存不夠'); 		mysqli_query($conn,"ROLLBACK"); 	}

      優(yōu)化2:文件鎖的思路

      對于日訪問量不高或者說并發(fā)數(shù)不是很大的應(yīng)用,用一般的文件操作方法完全沒有問題。但如果并發(fā)高,在我們對文件進(jìn)行讀寫操作時(shí),很有可能多個(gè)進(jìn)程對進(jìn)一文件進(jìn)行操作,如果這時(shí)不對文件的訪問進(jìn)行相應(yīng)的獨(dú)占,就容易造成數(shù)據(jù)丟失。

      <?php //優(yōu)化方案2:使用非阻塞的文件排他鎖 	include ('./mysql.php'); 	//生成唯一訂單號 	function build_order_no(){ 	  return date('ymd').substr(implode(NULL, array_map('ord', str_split(substr(uniqid(), 7, 13), 1))), 0, 8); 	}   	//記錄日志 	function insertLog($event,$type=0){ 		global $conn; 		$sql="insert into ih_log(event,type) 		values('$event','$type')"; 		mysqli_query($conn,$sql); 	} 	$fp = fopen("lock.txt", "w+"); 	if(!flock($fp,LOCK_EX | LOCK_NB)){ 		echo "系統(tǒng)繁忙,請稍后再試"; 		return; 	}   	//下單 	$sql="select number from ih_store where goods_id='$goods_id' and sku_id='$sku_id'"; 	$rs =  mysqli_query($conn,$sql); 	$row = $rs->fetch_assoc(); 	if($row['number']>0){//庫存是否大于0 		//模擬下單操作 		$order_sn=build_order_no(); 		$sql="insert into ih_order(order_sn,user_id,goods_id,sku_id,price) 		values('$order_sn','$user_id','$goods_id','$sku_id','$price')"; 		$order_rs =  mysqli_query($conn,$sql); 		//庫存減少 		$sql="update ih_store set number=number-{$number} where sku_id='$sku_id'"; 		$store_rs =  mysqli_query($conn,$sql); 		if($store_rs){ 			echo '庫存減少成功'; 			insertLog('庫存減少成功'); 			flock($fp,LOCK_UN);//釋放鎖 		}else{ 			echo '庫存減少失敗'; 			insertLog('庫存減少失敗'); 		} 	}else{ 		echo '庫存不夠'; 		insertLog('庫存不夠'); 	} 	 	fclose($fp);

      贊(0)
      分享到: 更多 (0)
      網(wǎng)站地圖   滬ICP備18035694號-2    滬公網(wǎng)安備31011702889846號