background

In normal development, we often face the problem of preventing duplicate requests. When a server’s response to a request involves data modification, or a change in state, it can cause significant harm. The consequences of repeated requests are particularly severe in transaction systems, after sales rights, and payment systems. But a lot of times, are looking to the front end to limit, such as after submission, button diseabled and so on, in fact, these are not reliable. Critical times still need the back end to verify.

The solution

1. Validation based on cached data state

Redis stores queries lightweight and fast. The request can be logged in the cache as it comes in. Subsequent incoming requests are validated each time. The entire process is processed and the cache is cleared.

if (! CacheExtension.getInstance().AddUnique($"{key}_unique", 1, DateTimeOffset. Now. AddDays (365))) {LogExtention. GetInstance () WriteCustomLogAsync (" ", "", true," end of batch has not yet implemented on "); Return ResponseResult.FromError(" Last batch has not finished execution!" ); } if (! string.IsNullOrEmpty(uniqueKey)) { CacheExtension.getInstance().Remove(uniqueKey); } return ResponseResult.Ok();Copy the code

2. Validation using a unique index mechanism

Atomic operations are required, thinking of a unique index to the database. Create a new table, insert data into the table each time the request comes in, and delete the record when the operation is complete.

Cache-based counter validation

Since database operations are performance-intensive, redis counters are also atomic operations. Be decisive with counters. It improves performance without storage and increases peak QPS. Each time the request comes in, create a new counter with orderId as key, and then +1. If the value is greater than 1 (the lock cannot be obtained), an operation is in progress. Delete it. If =1 (get lock) : ok to operate.

Redis > SET test 20 OK redis> INCR test (integer) 21 redis> GET test # Save "21" as a string in redis // GET all the specified counters HGETALL HMGET counter:user:{userID} praiseCnt hostCnt HINCRBY counter:user:{userID}  praiseCntCopy the code

conclusion

1. C# itself has a lock mechanism, singleton mode can be used.

2. However, considering our distributed deployment, caching is recommended. In the case of large concurrency, the occurrence of various program conditions. Especially when it comes to monetary manipulation. Therefore, in the case of mutually exclusive large concurrency, two schemes can be considered: 2 and 3.