ホームページ  >  記事  >  バックエンド開発  >  PHP で同時実行性を処理するためのテクニックは何ですか?

PHP で同時実行性を処理するためのテクニックは何ですか?

(*-*)浩
(*-*)浩オリジナル
2019-10-10 09:03:132329ブラウズ

この記事の例では、PHP 開発における同時実行の問題を解決するためのいくつかの実装方法について説明します。参考までに皆さんと共有します。詳細は次のとおりです。

PHP で同時実行性を処理するためのテクニックは何ですか?

## 製品の急ぎ購入、売られすぎなどの同時シナリオの場合

#PHP 言語にはネイティブの同時実行ソリューションがないため、他の方法を使用して同時実行制御を実現する必要があります。

オプション 1: ファイル ロックの排他的ロックを使用する

(推奨学習: PHP ビデオ チュートリアル )flock 関数は、ファイル ロックを取得するために使用されます。このロックを同時に取得できるのは 1 つのスレッドだけです。ロックを取得していない他のスレッドはブロックされるか、取得が失敗します。

ロックを取得するときは、最初にインベントリをクエリします。インベントリが0 より大きい場合は注文します。操作して在庫を減らし、ロックを解放します。

オプション 2: Mysql データベースによって提供される悲観的ロックを使用します。

Innodbストレージ エンジンは行レベルのロックをサポートしています。データ行がロックされている場合、現時点では、他のプロセスはこのデータ行を操作できません

#クエリを実行し、最初に行をロックします:

select stock_num from table where id=1 for update
if(stock_num > 0){
//下订单
update table set stock_num=stock-1 where id=1
}

オプション 3: キューを使用する

注文リクエストは順番にキューに保存され、別のプロセスがバックグラウンドで使用されてキュー内の注文リクエストが処理されます

オプション 4: Redis を使用する

Redis の操作はすべてアトミックです。商品の在庫を Redis に保存できます。注文する前に、在庫に対して Decr 操作を実行します。戻り値が 0 以上の場合は注文できます。それ以外の場合は注文できません。この方法の方が効率的です。

if(redis->get('stock_num') > 0){
 stock_num = redis->decr('stock_num')
 if(stock_num >= 0){
 //下订单
 }else{
 //库存不足
 }
}else{
//库存不足
}

その他の並行性の問題:

実際のアプリケーションでは、多くの場合、データはキャッシュに保存されます。キャッシュに障害が発生した場合は、データベースにアクセスしてデータを取得し、キャッシュをリセットします。このとき、同時実行量が非常に大きい場合、 、同時にデータを取得するために多くのプロセスがデータベースにアクセスすることになり、その結果、多くのリクエストが発生して

データベースに侵入し、データベースがクラッシュします。この問題を解決するにはファイル ロックを使用できます

$data = $cache->get('key');
if(!$data){
  $fp = fopen('lockfile');
  if(flock($fp, LOCK_EX)){
    $data = $cache->get('key');//拿到锁后再次检查缓存,这时可能已经有了
    if(!$data){
      $data = mysql->query();
      $cache->set('key', $data);
    }
    flock($fp, LOCK_UN);
  }
  fclose($fp);
}

端的に言えば、同時実行の問題を解決するにはロックが必要です。さまざまなソリューションの本質はロックです

以上がPHP で同時実行性を処理するためのテクニックは何ですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

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