>백엔드 개발 >PHP 문제 >PHP에서 높은 동시성을 처리하는 방법

PHP에서 높은 동시성을 처리하는 방법

(*-*)浩
(*-*)浩원래의
2019-09-12 09:51:092752검색

높은 동시성에서의 데이터 보안

우리는 여러 스레드가 동일한 파일에 쓸 때 "스레드 안전" 문제가 발생한다는 것을 알고 있습니다(여러 스레드가 동일하게 실행됨). 각 실행의 결과가 단일 스레드 실행의 결과와 동일하고 결과가 예상과 동일하면 스레드로부터 안전합니다.

PHP에서 높은 동시성을 처리하는 방법

MySQL 데이터베이스라면 자체 잠금 메커니즘을 사용하면 문제를 잘 해결할 수 있지만 대규모 동시성 시나리오에서는 그렇지 않습니다. 불가능합니다. MySQL을 사용하는 것이 좋습니다. 반짝 세일과 급매 시나리오에서 가장 중요한 문제는 '과잉 발행'이다. 이 부분을 세심하게 관리하지 않으면 실제 주문량이 예약 판매 상품보다 많아지는 문제가 발생한다.

과도하게 게시하는 이유: (권장 학습: 초보부터 마스터까지 PHP 프로그래밍)

그 누군가 이 급하게 구매하는 시나리오에서 우리는 총 100개의 제품만 가지고 있었습니다. 마지막 순간에 우리는 99개의 제품을 소비했고 마지막 제품만 남았습니다. 이때 시스템은 여러 개의 동시 요청을 보냈고, 이러한 요청으로 읽은 상품 잔액은 모두 1이었으며, 이후 모두 잔액 판단을 통과하여 결국 초과 발행으로 이어졌습니다.

주의할 점: 인벤토리 필드 번호 필드를 unsigned로 설정하는 것을 잊지 마세요. 인벤토리가 0이면 unsigned 필드는 음수가 될 수 없으므로 false가 반환됩니다.

#🎜 🎜##🎜 🎜#최적화 계획

Optimization 1: MySQL 트랜잭션을 사용하여 작업 행 잠그기 BEGIN ... FOR UPDATE ; 🎜🎜#

최적화 2: 파일 잠금 아이디어

일일 방문 횟수가 많지 않거나 동시 실행 횟수가 그리 크지 않은 애플리케이션의 경우, 일반적인 파일 조작 방법을 사용하면 문제가 없습니다. 그러나 동시성이 높으면 파일을 읽고 쓸 때 다음 파일에 대해 여러 프로세스가 작동할 가능성이 매우 높습니다. 이때 파일에 대한 액세스가 배타적이지 않으면 쉽게 데이터 손실이 발생할 수 있습니다.

<?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");
	}

위 내용은 PHP에서 높은 동시성을 처리하는 방법의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.