Maison  >  Article  >  développement back-end  >  PHP implémente une fonction de capture simultanée via le verrouillage

PHP implémente une fonction de capture simultanée via le verrouillage

*文
*文original
2017-12-29 18:09:042351parcourir

Cet article est basé sur le langage PHP et utilise le verrouillage pour implémenter la fonction d'achat urgent dans des circonstances concurrentes. L'achat urgent est ouvert pendant une période de temps spécifique et ne permet pas la duplication de codes ouverts. Cet article est très détaillé, n'hésitez pas à vous y référer si vous en avez besoin. J'espère que cela aide tout le monde.

Exigences : fonction de saisie de code

Exigences :

1. La saisie de code n'est ouverte que pendant une période spécifique

.

2. Les codes publiés dans chaque période sont limités

3. Chaque code ne peut pas être répété

Réalisation :

1. Implémenté sans tenir compte de la concurrence :

<p style="margin-top: 5px; margin-bottom: 5px;">function get_code($len){<br/>$CHAR_ARR = array(&#39;1&#39;,&#39;2&#39;,&#39;3&#39;,&#39;4&#39;,&#39;5&#39;,&#39;6&#39;,&#39;7&#39;,&#39;8&#39;,&#39;9&#39;,&#39;A&#39;,&#39;B&#39;,&#39;C&#39;,&#39;D&#39;,&#39;E&#39;,&#39;F&#39;,&#39;G&#39;,&#39;H&#39;,&#39;I&#39;,&#39;J&#39;,&#39;K&#39;,&#39;L&#39;,&#39;M&#39;,&#39;N&#39;,&#39;O&#39;,&#39;P&#39;,&#39;Q&#39;,&#39;X&#39;,&#39;Y&#39;,&#39;Z&#39;,&#39;W&#39;,&#39;S&#39;,&#39;R&#39;,&#39;T&#39;);<br/>$CHAR_ARR_LEN = count($CHAR_ARR) - 1;<br/>$code = &#39;&#39;;<br/>while(--$len > 0){ $code .= $CHAR_ARR[rand(0,$CHAR_ARR_LEN)]; }<br/>return $code;<br/>}<br/>$pdo = new PDO(&#39;mysql:host=localhost;dbname=ci_test&#39;,&#39;root&#39;,&#39;root&#39;);<br/>//查询当前时间已发放验证码数量<br/>$code_num_rs = $pdo->query("SELECT COUNT(*) as sum FROM code_test");<br/>$code_num_arr = $code_num_rs->fetch(PDO::FETCH_ASSOC);<br/>$code_num = $code_num_arr[&#39;sum&#39;];<br/>if($code_num < 1){<br>   sleep(2); //暂停2秒<br/>$code = get_code(6);<br/>var_dump( $pdo->query("INSERT INTO code_test (code,create_time) VALUES (&#39;$code&#39;,".time().")") );<br/>}<br/></p>

Le code ci-dessus satisfait à l'heure d'ouverture actuelle par défaut, et le code n'est pas répété

Sans tenir compte de la concurrence ;

1) Sélectionnez et interrogez le nombre de codes de vérification émis par la base de données actuelle

2) S'il reste des places, générez le code de vérification, insérez-le dans la base de données et renvoyer le code de vérification au client ;

3) S'il est plein ; renvoyer un message indiquant qu'il n'y a plus de places

2. Mis en œuvre dans des situations concurrentes :

Jetez ensuite un œil aux résultats obtenus par le code ci-dessus dans le cas de la concurrence :

Pour tester la concurrence, vous pouvez utiliser Apache Benchmark pour test. apache benchmark est l'outil d'évaluation des performances du SERVEUR HTTP sous APACHE, via cmd Entrez le répertoire bin d'apche et appelez-le via la commande ab, telle que : ab -c nombre simultané -n url total des visites

<p style="margin-top: 5px; margin-bottom: 5px;">cb -c 100 -n 100 http://localhost/php_mulit.php<br/></p>

De cette façon, 100 utilisateurs et collègues récupéreront 1 quota. À ce moment-là, si chaque utilisateur constate qu'il y a encore un quota, le code de vérification sera généré, inséré dans la base de données, et le code de vérification sera généré. sera renvoyé ; cela entraînera l’envoi d’un trop grand nombre de codes de vérification. En fait, après avoir exécuté cette commande, la base de données contient 13 enregistrements supplémentaires au lieu d'un.

Comment éviter que cela se produise ?

Vous pouvez verrouiller le processus du jugement à l'insertion en ajoutant un verrou exclusif pour garantir qu'un seul processus est en cours d'exécution dans ce processus de jugement à tout moment. La mise en œuvre est la suivante :

<p style="margin-top: 5px; margin-bottom: 5px;">//生成码<br/>function get_code($len){<br/>$CHAR_ARR = array(&#39;1&#39;,&#39;2&#39;,&#39;3&#39;,&#39;4&#39;,&#39;5&#39;,&#39;6&#39;,&#39;7&#39;,&#39;8&#39;,&#39;9&#39;,&#39;A&#39;,&#39;B&#39;,&#39;C&#39;,&#39;D&#39;,&#39;E&#39;,&#39;F&#39;,&#39;G&#39;,&#39;H&#39;,&#39;I&#39;,&#39;J&#39;,&#39;K&#39;,&#39;L&#39;,&#39;M&#39;,&#39;N&#39;,&#39;O&#39;,&#39;P&#39;,&#39;Q&#39;,&#39;X&#39;,&#39;Y&#39;,&#39;Z&#39;,&#39;W&#39;,&#39;S&#39;,&#39;R&#39;,&#39;T&#39;);<br/>$CHAR_ARR_LEN = count($CHAR_ARR) - 1;<br/>$code = &#39;&#39;;<br/>while(--$len > 0){ $code .= $CHAR_ARR[rand(0,$CHAR_ARR_LEN)]; }<br/>return $code;<br/>}<br/>$pdo = new PDO(&#39;mysql:host=localhost;dbname=ci_test&#39;,&#39;root&#39;,&#39;root&#39;);<br/>$fp = fopen(&#39;lock.txt&#39;,&#39;r&#39;);<br/>//通过排他锁 锁定该过程<br/>if(flock($fp,LOCK_EX)){<br/>//查询当前时间已发放验证码数量<br/>$code_num_rs = $pdo->query("SELECT COUNT(*) as sum FROM code_test");<br/>$code_num_arr = $code_num_rs->fetch(PDO::FETCH_ASSOC);<br/>$code_num = $code_num_arr[&#39;sum&#39;];<br/>if($code_num < 1){<br/>sleep(2);<br/>$code = get_code(6);<br/>var_dump( $pdo->query("INSERT INTO code_test (code,create_time) VALUES (&#39;$code&#39;,".time().")") );<br/>}<br/>flock($fp,LOCK_UN);<br/>fclose($fp);<br/>}<br/></p>

Verrouillez le processus via la fonction flock.

Exécutez-le à nouveau

<p style="margin-top: 5px; margin-bottom: 5px;">cb -c 100 -n 100 http://localhost/php_mulit.php<br/></p>

Un seul enregistrement est ajouté à la base de données, garantissant que les données sont correctes en cas de simultanéité.

Recommandations associées :

Exploration approfondie pour savoir si php continuera à s'exécuter après la fermeture du navigateur

Exemple de la façon dont PHP implémente le carnet d'adresses en ligne

Comparaison d'exemples de la façon dont PHP peut lire efficacement des fichiers volumineux

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn