PHP implements concurrent snap-up function through locking

*文
Release: 2023-03-18 20:24:01
Original
2403 people have browsed it

This article uses locking based on the PHP language to implement the rush purchase function under concurrent circumstances. The rush purchase is open during a specific period of time and does not allow duplication of open codes. This article is very detailed, please refer to it if you need it. I hope to be helpful.

Requirements: code grabbing function

Requirements:

1. Code grabbing is only open during a specific time period;

2. The codes released in each time period are limited;

3. Each code is not allowed to be repeated;

Implementation:

1. Implementation without considering concurrency:

<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>
Copy after login

The above code satisfies the current opening time by default, and the code is not repeated;

The process without considering concurrency:

1) Select to query the number of verification codes issued by the current database;

2) If there are still places, generate the verification code, insert it into the database, and return the verification code to Client;

 3) If it is full; it will return a prompt that there are no more places;

2. Implementation under concurrent circumstances:

Then take a look at the results obtained by the above code in a concurrent situation:

To test concurrency, you can use apache benchmark to test. apache benchmark is the performance evaluation tool of HTTP SERVER under APACHE. Enter through cmd In the bin directory of apche, call it through the ab command, such as: ab -c concurrent number -n total visits url

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

In this way, 100 user colleagues will grab 1 quota. When querying, each When users check that there is still a quota, they will generate a verification code, insert it into the database, and return the verification code; this will cause too many verification codes to be issued. In fact, after running this command, the database has 13 more records instead of one.

How to avoid this happening?

You can lock the process from judgment to insertion by adding an exclusive lock to ensure that only one process is running in this judgment process at any time. The implementation is as follows:

<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>
Copy after login

Lock the process through flock function.

Run again

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

Only one record is added to the database, ensuring that the data is correct under concurrent conditions.

Related recommendations:

In-depth exploration of whether php will continue to execute after the browser exits

#Example of php implementing online address book

Comparison of examples of how PHP can efficiently read large files

The above is the detailed content of PHP implements concurrent snap-up function through locking. For more information, please follow other related articles on the PHP Chinese website!

Related labels:
source:php.cn
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template
About us Disclaimer Sitemap
php.cn:Public welfare online PHP training,Help PHP learners grow quickly!