The interviewer asked: what is the solution to prevent duplicate requests?

Time:2021-6-11

background

In normal development, we often face the problem of preventing duplicate requests. When the server response to the request involves data modification or state change, it may cause great harm. The consequences of repeated requests are especially serious in the transaction system, after-sales rights protection and payment system. But most of the time, they rely on the front end to limit, such as the button disabled after submitting. In fact, these are unreliable. At the critical time, the back end is still needed to verify.

Solutions

1. Verification based on cache data state

Redis storage query is light and fast. When a request comes in, it can be recorded in the cache first. The subsequent requests are verified each time. The whole process is finished and the cache is cleared.

if (!CacheExtension.getInstance().AddUnique($"{key}_unique", 1, DateTimeOffset.Now.AddDays(365)))
            {
                Logextension. Getinstance(). Writecustomlogasync (',', true, 'last batch has not finished yet');
                Return responseresult. Fromerror ("the last batch has not been executed yet!");
            }
 if (!string.IsNullOrEmpty(uniqueKey))
            {
                CacheExtension.getInstance().Remove(uniqueKey);
            }
            return ResponseResult.Ok();

 

2. Verification using unique index mechanism

Need atomic operation, thought of the database unique index. Create a new table, and insert data into the table every time the request comes in,   After the operation, delete the record.

 

 

 

3. Counter verification based on cache

Because the operation of database consumes more performance, we know that the counter of redis is also atomic operation. Use the counter decisively. It can not only improve the performance without storage, but also improve the peak value of QPS.   Each time the request comes in, create a new counter with OrderID as the key, and then + 1. If > 1 (unable to obtain lock): it indicates that there is an operation in progress, delete it. If = 1 (get lock): can be operated.

redis> SET test 20
OK
redis> INCR test
(integer) 21
Redis > get test # numeric values are saved as strings in redis
"21"

//Gets all counters specified
HGETALL counter:user:{userID}   

//Gets the specified counter
HMGET counter:user:{userID}  praiseCnt hostCnt 

//Specified likes + 1
HINCRBY counter:user:{userID}   praiseCnt

 

summary

1. C # has its own lock mechanism, and monomer mode can be used.

2. However, considering our distributed deployment, it is recommended to use caching. In the case of large concurrency, the occurrence of various conditions of the program. Especially when it comes to the amount operation. Therefore, in the case of mutual exclusion of large concurrency, we can consider two or three schemes.