We know that database processing SQL is handled in a way that assumes that the process of buying a product is this:
SQL1: Check Commodity inventory
If (inventory quantity > 0)
{
//Generate order ...
SQL2: Stock-1
}
When there is no concurrency, the above process looks so perfect, suppose that at the same time two people under a single, and inventory only 1, in the SQL1 stage of two people to query the inventory is >0, then eventually implemented the SQL2, inventory finally turned to-1, the sale, or replenishment inventory, or other users complained about it.
The more popular way to solve this problem:
1. With an additional single process to process a queue, the next single request into the queue, processing, there will be no concurrent problems, but to the additional background process and delay issues, not considered.
2. Database optimistic lock, the general meaning is to query the inventory, and then immediately inventory +1, and then after the order is generated, in the update inventory before checking the inventory, to see if the inventory quantity is consistent with the expected, inconsistent roll back, prompting the user inventory is insufficient.
3. According to the update results to judge, we can add a judgment condition in SQL2 update ... where inventory >0, if False, indicates that there is not enough inventory and rolls back the transaction.
4. With the help of file exclusive lock, when processing the order request, with flock lock a file, if the lock failed to indicate that there are other orders are processing, at this time either wait or directly prompt the user "server Busy"
This article is about the 4th scenario, the approximate code is as follows:
Blocking (Waiting) mode
<?php
$fp = fopen ("Lock.txt", "w+");
if (Flock ($FP, lock_ex))
{
///.. Processing order
Flock ($FP, lock_un);
Fclose ($FP);
? >
Non-blocking mode
<?php
$fp = fopen ("Lock.txt", "w+");
if (Flock ($fp, LOCK_EX | LOCK_NB))
{
///.. Processing order
Flock ($FP, lock_un);
else
{
echo "system busy, please try again later";
}
Fclose ($FP);
? >