Requirement: 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. Duplication of each code is not allowed;
Implementation:
1. Implement without considering concurrency:
function get_code($len){ $CHAR_ARR = array('1','2','3','4','5','6','7','8','9','A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','X','Y','Z','W','S','R','T'); $CHAR_ARR_LEN = count($CHAR_ARR) - 1; $code = ''; while(--$len > 0){ $code .= $CHAR_ARR[rand(0,$CHAR_ARR_LEN)]; } return $code; } $pdo = new PDO('mysql:host=localhost;dbname=ci_test','root','root'); //查询当前时间已发放验证码数量 $code_num_rs = $pdo->query("SELECT COUNT(*) as sum FROM code_test"); $code_num_arr = $code_num_rs->fetch(PDO::FETCH_ASSOC); $code_num = $code_num_arr['sum']; if($code_num < 1){<br> sleep(2); //暂停2秒 $code = get_code(6); var_dump( $pdo->query("INSERT INTO code_test (code,create_time) VALUES ('$code',".time().")") ); }
The above code satisfies the current opening hours by default, and the codes are not repeated;
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 a verification code, insert it into the database, and return the verification code to the client;
3) If it is full; it will return a prompt that there are no more places;
2. Implementation under concurrent conditions:
Then take a look at the results obtained by the above code under concurrent conditions:
To test concurrency, you can use apache benchmark. Apache benchmark is the performance evaluation tool of HTTP SERVER under APACHE. Enter the bin directory of apche through cmd and call it through the ab command, such as: ab -c concurrent number -n total visits Measure url
In this way, 100 users and colleagues are trying to grab 1 quota. During the query, if each user finds that there is still a quota, the verification code will be generated, inserted into the database, and the verification code will be returned; this will cause the verification code to be issued. too much. 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:
//生成码 function get_code($len){ $CHAR_ARR = array('1','2','3','4','5','6','7','8','9','A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','X','Y','Z','W','S','R','T'); $CHAR_ARR_LEN = count($CHAR_ARR) - 1; $code = ''; while(--$len > 0){ $code .= $CHAR_ARR[rand(0,$CHAR_ARR_LEN)]; } return $code; } $pdo = new PDO('mysql:host=localhost;dbname=ci_test','root','root'); $fp = fopen('lock.txt','r'); //通过排他锁 锁定该过程 if(flock($fp,LOCK_EX)){ //查询当前时间已发放验证码数量 $code_num_rs = $pdo->query("SELECT COUNT(*) as sum FROM code_test"); $code_num_arr = $code_num_rs->fetch(PDO::FETCH_ASSOC); $code_num = $code_num_arr['sum']; if($code_num < 1){ sleep(2); $code = get_code(6); var_dump( $pdo->query("INSERT INTO code_test (code,create_time) VALUES ('$code',".time().")") ); } flock($fp,LOCK_UN); fclose($fp); }
Lock the process through flock function.
For more flock information, please refer to the php manual: http://php.net/manual/zh/function.flock.php
Run again
Only one record is added to the database, ensuring the accuracy of data under concurrent conditions.
The above is the editor’s introduction to PHP’s code grabbing function under concurrency through locking. I hope it will be helpful to you. If you have any questions, please leave me a message and the editor will reply to you in time. I would also like to thank everyone for your support of the Script House website!