1. 過剰発行の理由
急ぎ購入のシナリオでは、合計で 100 製品しかないとします。最後の瞬間、購入した商品は 99 個消費され、最後の 1 個だけが残っています。このとき、システムは複数のリクエストを同時に送信し、そのリクエストで読み取った商品残高が99個すべてで残高判定を通過し、最終的に発行過剰に陥ってしまいました。
上の図では、同時ユーザー B も「購入に成功」し、さらに 1 人が製品を入手できるようになりました。このシナリオは、同時実行性が高い状況で非常に発生しやすくなります。
ファイル ロックのアイデア
日次 IP が高くない、または同時実行数がそれほど多くないアプリケーションの場合は、通常、これらを考慮する必要はありません。通常のファイル操作方法では全く問題ありません。しかし、同時実行性が高い場合、ファイルの読み書きを行うときに、次のファイルに対して複数のプロセスが動作する可能性が高く、このときファイルへのアクセスが排他的でない場合、データ損失が発生しやすくなります。
最適化ソリューション: ノンブロッキング ファイル排他ロックを使用する
<?php //优化方案4:使用非阻塞的文件排他锁 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 "系统繁忙,请稍后再试"; 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); ?>
推奨チュートリアル: PHP ビデオ チュートリアル
以上がPHPでの同時実行性の高さを防ぐ方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。