ホームページ >バックエンド開発 >PHPの問題 >PHPでの高い同時実行性に対処する方法

PHPでの高い同時実行性に対処する方法

(*-*)浩
(*-*)浩オリジナル
2019-09-12 09:51:092752ブラウズ

高同時実行時のデータ セキュリティ

複数のスレッドが同じファイルに書き込むと、「スレッドの安全性」の問題が発生することがわかっています (複数のスレッドが同じセグメントを同時に実行します)各実行の結果がシングルスレッド実行の結果と同じであり、結果が期待どおりである場合、コードはスレッドセーフです)。

PHPでの高い同時実行性に対処する方法

MySQL データベースの場合は、独自のロック メカニズムを使用して問題を解決できますが、大規模な同時実行シナリオでは、MySQL はお勧めできません。フラッシュセールや駆け込み販売の場合、最も重要な問題は「過剰発行」であり、この点を慎重にコントロールしないと、実際に発生する注文が予約販売商品を上回るという問題が発生します。

過剰投稿の理由: (推奨される学習: PHP プログラミングの入門から熟練度まで )

特定の急ぎ購入シナリオで次のように仮定します。 、製品は 100 個しかありませんが、最後の瞬間に 99 製品を消費し、最後の 1 つだけが残りました。このとき、システムは複数のリクエストを同時に送信し、そのリクエストで読み取られた商品残高がすべて1であった後、すべて残高判定を通過し、最終的に発行過剰に陥りました。

##注目に値します: 在庫フィールド番号フィールドを符号なしに設定することを忘れないでください。在庫が 0 の場合、符号なしフィールドは負の数値にすることができないため、false が返されます

最適化計画

最適化 1: MySQL トランザクションを使用して操作 BEGIN ; SELECT ... FOR UPDATE ; COMMIT ; ROLLBACK

<?php
	//优化方案1:使用MySQL的事务,锁住操作的行
	include(&#39;./mysql.php&#39;);
	function build_order_no(){
		return date(&#39;ymd&#39;).substr(implode(NULL, array_map(&#39;ord&#39;, str_split(substr(uniqid(), 7, 13), 1))), 0, 8);
	}
	//记录日志
	function insertLog($event,$type=0){
		global $conn;
		$sql="insert into ih_log(event,type)
		values(&#39;$event&#39;,&#39;$type&#39;)";
		mysqli_query($conn,$sql);
	}
	
	mysqli_query($conn,"BEGIN");  //开始事务
	$sql="select number from ih_store where goods_id=&#39;$goods_id&#39; and sku_id=&#39;$sku_id&#39; FOR UPDATE";//此时这条记录被锁住,其它事务必须等待此次事务提交后才能执行
	$rs=mysqli_query($conn,$sql);
	$row=$rs->fetch_assoc();
	
	if($row[&#39;number&#39;]>0){
		//生成订单
		$order_sn=build_order_no();
		$sql="insert into ih_order(order_sn,user_id,goods_id,sku_id,price)
			values(&#39;$order_sn&#39;,&#39;$user_id&#39;,&#39;$goods_id&#39;,&#39;$sku_id&#39;,&#39;$price&#39;)";
		$order_rs=mysqli_query($conn,$sql);
		//库存减少
		$sql="update ih_store set number=number-{$number} where sku_id=&#39;$sku_id&#39;";
		$store_rs=mysqli_query($conn,$sql);
		if($store_rs){
		  echo &#39;库存减少成功&#39;;
			insertLog(&#39;库存减少成功&#39;);
			mysqli_query($conn,"COMMIT");//事务提交即解锁
		}else{
		  echo &#39;库存减少失败&#39;;
			insertLog(&#39;库存减少失败&#39;);
		}
	}else{
		echo &#39;库存不够&#39;;
		insertLog(&#39;库存不够&#39;);
		mysqli_query($conn,"ROLLBACK");
	}

最適化 2: ファイルロックのアイデア

毎日のアクセス数が多くない、または同時実行数がそれほど多くないアプリケーションの場合は、一般的なファイル操作方法を使用しても問題ありません。しかし、同時実行性が高い場合、ファイルの読み書きを行う際に、次のファイルに対して複数のプロセスが動作する可能性が高く、それに応じてファイルへのアクセスが独占されないと、データの損失が発生しやすくなります。

rree

以上がPHPでの高い同時実行性に対処する方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。