How to ensure idempotency interface. . . . .

In the micro-service architecture, we often encounter the following scene at the completion of an order process:

  1. An order creating an interface, the first call timeout, and then once the caller to retry
  2. When an order is created, we need to deduct inventory, then the interface timeout occurred, a caller to retry
  3. When this order to start paying after the payment request is made, the server took place in deducting money operation, the interface response timeout, and retries a caller
  4. An order status update interface, the caller sends two messages in a row, one has been created, one is paid. But first you have received payment and then received that have been created
  5. After the completion of the payment order, you need to send a message, after receiving a machine SMS message, the process is slow. Message middleware message delivered again to another machine processing

After the above problem is to turn into micro-architecture in monomer services architecture, brings problems. Of course not to say that none of these issues under the framework monomers, the monomers in the same framework to avoid duplication request. But the problem is much less than this.

To solve this problem, we need to ensure that idempotency interface idempotency interface, the interface is actually repeated calls, in the case of multiple calls to the caller, the result ultimately get the interface is consistent. Some interfaces can achieve natural idempotency, such as query interface , for query, you query once and twice, for the system, no effect, isolated result is the same.

In addition to the search function has a natural idempotent, add, update, delete must ensure idempotency. So how to ensure idempotency it?

Globally Unique ID

If a globally unique ID, and the content of the service is operating a global ID is generated according to, before performing operations in accordance with the globally unique ID exists, to determine whether the operation has been performed. If there is put a global ID, stored in the storage system, such as a database, Redis like. If there is indicates that the method has been performed.

From an engineering point of view, the use of global ID, etc. can be used as a power to do business on the basis of micro-services exist in many micro services will be used in such a service, such functions are completed in each micro-services, will there is repeated workload. In addition to create a highly reliable power and other services also need to consider many issues, such as a machine although the global ID to write the memory, but hung up after writing, which requires the introduction of a global ID of the timeout mechanism.

Using globally unique ID is a generic solution that can support insert, update, delete business operations. But the realization of this program looks beautiful but too much trouble, the following scheme applies to a particular scene, but simple to implement.

De-duplication table

This method is suitable for insertion in the scene with a unique subject in the business, such as in the above payment scenario, if an order will only be paid once, so you can order ID as a unique identifier. At this point, we can go to build a heavy table, and the unique identification as a unique index, when we realize, to create documents and written over and over again to pay heavy table, in a transaction, if recreating the database will The only constraint throws an exception, the operation will be rolled back.

Insert or update

This method has the case and inserting a unique index, such as we want to associate the category of goods, wherein the product ID and category ID may constitute a unique index, and the data in the table also increases the unique index. Then you can use InsertOrUpdate operation. In mysql database as follows:

1
2
3
4
insert into goods_category (goods_id,category_id,create_time,update_time)
values(#{goodsId},#{categoryId},now(),now())
on DUPLICATE KEY UPDATE
update_time= now()

Multi-Versioning

This method is suitable in the updated scenario, for example, we want to update the name of the goods, then we can add a version number in the updated interface, do idempotent

1
boolean updateGoodsName(int id,String newName,int version);

When implemented may be as follows

 

1
update goods set name=#{newName},version=#{version} where id=#{id} andversion<${version}


1. achieved by version 
update table_xxx set name = # name #  , version = version + 1 where version = # version #
below (from the Internet): 

 

2. conditions 
update table_xxx set avai_amount = avai_amount- # subAmount # where avai_amount - # subAmount #> = 0 
requirements: quality- # subQuality #> =, do not fit this scenario version number, the update is only for data security check for inventory model, buckle share and share rollback, higher performance 

Note: optimism lock update operation, preferably with the updated primary key or unique index, this row is locked, or when the update lock table, the above two into the following two sql better 
update table_xxx set name = # name # , version = +. 1 WHERE ID = Version ID # and # # = Version Version # 
Update table_xxx SET avai_amount = avai_amount- subAmount # # # WHERE ID = avai_amount- ID # and # # subAmount> = 0
 

State machine controls

This method is suitable in the presence of the state machine transfer of cases, such as creates and payment orders, payment orders must be in before, then we can pass in the design of state field, use the int type, and by value types size do idempotent, such as creating an order of 0, 100 payment was successful. Payment failed 99

In doing state machine updates, so we can control it

1
update `order` set status=#{status} where id=#{id} and status<#{status}

These are some of the ways to ensure the power of the interface and so on.

10. How to provide external interfaces api ensure idempotent 
such as UnionPay to provide payment interfaces: comes when access is required to submit merchant payment request: source source, seq serial number 
source + seq make a unique index in a database to prevent multiple payments, ( concurrent, can only handle one request) 

focus: 
provide external interfaces to support idempotent call interface has two fields must pass, is the source of a source, a source side serial number is seq, the two fields in which the provider system the only index to do joint, so that when a third-party call, first check the local system inside it, whether processed, the processing returns to the corresponding results; not dealt with, and dealt with accordingly, returns the result. Note that in order idempotent friendship, be sure to inquire about whether treated this transaction, does not query directly into business systems, will complain, but actually has been processed.
 


Summary: 
Idempotence should be a qualified programmer of a gene, in the design of the system, is the primary consideration, especially in a system like pay all the money involved in the treasure, banks, finance companies and other Internet, it is necessary to efficient data should be accurate, it can not appear more than chargeback, and more play money and other issues, it will difficult to handle, the user experience is not good 

Guess you like

Origin www.cnblogs.com/hellohorld/p/11141137.html