1, Meaning
Idempotency: the final result of 1 submission and 100 submissions is the same. The result of the first power of 1 and the 100th power of 1 is 1
2, What is idempotency
Interface idempotency means that the results of one request or multiple requests initiated by the user for the same operation are consistent and will not be changed
Side effects caused by multiple clicks; For example, in the payment scenario, the user purchases a commodity, and the payment deduction is successful, but the settlement is returned
If the network is abnormal, the money has been deducted. The user clicks the button again. At this time, the second deduction will be made and the settlement will be returned
If it is successful, the user finds that the balance is deducted too much, and the daily record has become two... There is no guaranteed interface
Idempotency of. 2, What situations need to be prevented
The user clicks the button multiple times
User page fallback and resubmit
Microservices call each other. The request fails due to network problems. feign trigger retry mechanism
Other business conditions
3, When do I need idempotent
Taking SQL as an example, some operations are naturally idempotent.
SELECT * FROM table WHER id=?, No matter how many times it is executed, it will not change the state and is a natural idempotent.
UPDATE tab1 SET col1=1 WHERE col2=2. The status is consistent no matter how many times the execution is successful. It is also an idempotent operation.
delete from user where userid=1. Multiple operations result in the same idempotent
insert into user(userid,name) values(1, 'a') if userid is the only primary key, that is, repeat the above business, only
A piece of user data will be inserted, which is idempotent.
UPDATE tab1 SET col1=col1+1 WHERE col2=2. The result of each execution will change, not idempotent.
insert into user(userid,name) values(1, 'a') if userid is not a primary key, it can be repeated. The above business operations are repeated
As a result, multiple pieces of data will be added, which is not idempotent.
4, Idempotent solution
4.1. token mechanism can also be a verification code
1,The server provides sending token Interface for. When analyzing businesses, which businesses have idempotent problems, You must obtain the information before executing the business token,The server will token Save to redis Yes. 2,Then call the business interface request. token Carry it over, usually on the request head. 3,Server judgment token Does it exist redis In, presence indicates the first request and then deletion token,Continue to carry out business. 4,If judge token non-existent redis In, it means that the operation is repeated, and the repeated flag is directly returned to client,such This ensures that the business code will not be executed repeatedly.
danger:
1,Delete first token Or delete after token; (1) Deleting first may cause the business to not be executed, and the retry will be brought before token,Due to anti weight design, The request still cannot be executed. (2) Post deletion may result in successful business processing, but the service is interrupted, timeout occurs, and no deletion occurs token,other People continue to retry, causing the business to be executed (3) We'd better design to delete it first token,If the business call fails, it is retrieved token Request again.
Solution: ensure that Token acquisition, comparison and deletion must be atomic
(1) redis.get(token) ,token.equals,redis.del(token)If these two operations are not atoms, they may be derivative To, high and fat, all get To the same data, the judgment is successful, and the business continues to be executed concurrently (2) Can be in redis use lua The script does this if redis.call('get', KEYS[1]) == ARGV[1] then return redis.call('del', KEYS[1]) else return 0 end
4.2. Various locking mechanisms
1. Database pessimistic lock
select * from xxxx where id = 1 for update; Pessimistic locks are generally used with transactions, and the data locking time may be very long, which should be selected according to the actual situation. Also note that, id The field must be a primary key or unique index, otherwise it may cause the result of locking the table and will be difficult to process Very troublesome.
2. Database optimistic lock
This method is suitable for updated scenarios, update t_goods set count = count -1 , version = version + 1 where good_id=2 and version = 1 according to version Version, that is, get the version of the current commodity before operating the inventory version Version number, and then when operating Take this with you version number. Let's sort it out. When we first operated the inventory, we got version For 1, call the inventory service version Became 2; However, there is a problem returning to the order service. The order service initiates to call the inventory service again Single service transmission version Or 1, and then execute the above sql Statement will not be executed; because version Has changed For 2, where The conditions are not tenable. This ensures that no matter how many times it is called, it will only be processed once. Optimistic lock is mainly used to deal with the problem of reading more and writing less
3. Business layer distributed lock
If multiple machines may process the same data at the same time, for example, multiple machines get the same number of scheduled tasks According to the processing, we can add a distributed lock to lock the data, and release the lock after the processing is completed. To obtain a lock, you must first judge Whether this data has been processed.
4.3. Various unique constraints
1. Database unique constraint
When inserting data, it should be inserted according to the unique index. For example, if the order number is the same, it is impossible to insert two records in the same order.
We prevent duplication at the database level.
This mechanism makes use of the unique constraint of the database primary key to solve the idempotent problem in the insert scenario. But the primary key
The requirement of is not a self increasing primary key, which requires the business to generate a globally unique primary key.
In the scenario of sub database and sub table, the routing rules should ensure that the same request is landed in the same database and the same table
Otherwise, the database primary key constraint will not work because different databases and table primary keys are not related.
2. redis set anti duplication
Many data need to be processed and can only be processed once. For example, we can calculate the MD5 of the data and put it into the set of redis,
Each time you process data, first check whether this MD5 already exists. If it exists, it will not be processed.
4.4 weight prevention table
Use the order number orderNo as the unique index of the de duplication table, insert the unique index into the de duplication table, and then carry out business operations, and
They are in the same business. This ensures that the request fails due to the unique constraint of the de duplication table when the request is repeated
The idempotent problem is avoided. It should be noted here that the de duplication table and the business table should be in the same database, so as to ensure that they are in the same database
Transaction, even if the business operation fails, will roll back the data of the de duplication table. This ensures data consistency.
redis weight prevention as mentioned before is also included
4.5. Global request unique id
When the interface is called, a unique id is generated. redis saves the data to the collection (de duplication). It is processed if it exists.
You can use nginx to set the unique id of each request;
proxy_set_header X-Request-Id $request_id;