Java idempotency interface design

Reprinted: https: //www.cnblogs.com/zxf330301/p/10079997.html

 

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 to 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} and version<${version}

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 that the interfaces idempotency

Guess you like

Origin www.cnblogs.com/xinruyi/p/11441861.html