PHP high concurrency solution

Recently, when I was working on a group buying project, I encountered a problem, that is, during the activities such as panic buying, seckill, and lottery, the number of stocks is limited, but at the same time, the number of people placing orders exceeds the number of stocks, which will lead to the problem of overselling of goods. So how do we solve this problem, my thinking is as follows: 

sql1: Query commodity inventory
if(stock quantity > 0)
{
  //Generate orders...
  sql2: inventory-1
}

 

When there is no concurrency, the above process looks so perfect. Suppose two people place an order at the same time, and there is only one inventory. In the sql1 stage, the inventory queried by the two people is > 0, so sql2 is finally executed. The inventory finally becomes -1, and it is oversold. Either replenish the inventory or wait for the user to complain.

 

 

 

The more popular ideas to solve this problem:

1. Use an additional single process to process a queue, place order requests in the queue, and process them one by one, there will be no concurrency problems, but additional background processes and delay problems will not be considered.

2. The database is optimistically locked, which roughly means to query the inventory first, then immediately increase the inventory by 1, and then after the order is generated, query the inventory again before updating the inventory to see if it is consistent with the expected inventory quantity, and roll back if it is inconsistent. , prompting the user that the inventory is low.

3. Judging from the update result, we can add a judgment condition update ... where inventory > 0 in sql2. If it returns false, it means that the inventory is insufficient and the transaction is rolled back.

4. With the help of file exclusive lock, when processing an order request, use flock to lock a file. If the lock fails, it means that other orders are being processed. At this time, either wait or directly prompt the user that "the server is busy"

 

 

 

This article is going to talk about the fourth scheme, the rough code is as follows:

blocking (waiting) mode

<?php
$fp = fopen("lock.txt", "w+");
if(flock($fp,LOCK_EX)) //Lock the current pointer,,,
{
  //.. process the order
  flock($fp,LOCK_UN);
}
fclose($fp);
?>
non-blocking mode
 
<?php
$fp = fopen("lock.txt", "w+");
if(flock($fp,LOCK_EX | LOCK_NB))
{
  //.. process the order
  flock($fp,LOCK_UN);
}
else
{
  echo "The system is busy, please try again later";
}
 
fclose($fp);
?>

 

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=326126214&siteId=291194637
Recommended