Solve problems on the settlement system interface idempotent

What is Idempotence?

For the same business operation, no matter how many times to call, in memory of the database, or the results obtained should be the same.

Idempotency design of

To recharge Alipay or micro-letter, for example, after we've paid, Alipay, micro-channel will give us a callback to inform our system successful payment, and before that, our system has been stored in this order information, we have to do the thing is the need to pay after the treasure or micro letter to the callback us, no matter how many times the callback, we should focus on the interface results in the same order get is the same.

For our system should have a unique product order number: out_trade_no

Alipay in the callback returned to us: out_trade_no [Merchant order number (own definition)], trade_no [Alipay transaction number]

Implementation idempotency interface

Method 1 (the most common and most convenient way, but there are problems):

Why I would say it is the most common of it, because it is the easiest to achieve, and there is not much thinking,

Processes such as the following:

  1. Receives a callback Alipay,
  2. According trade_no out_trade_no query the database and order information, the order is being processed
  3. If the order has been processed, the direct return, if untreated continue down
  4. Enable local affairs,
  5. Local user account to add money to the system
  6. The order status changed to trading success
  7. Submit local transaction

Thinking:

The way it seems appropriate, however, if Alipay, micro letter to inform us many times, at the same time to step two, what will happen then? Obviously, to inquire orders are untreated, the situation is many times more money to the account of it will happen, so we are most commonly used in this way is problematic

Second way (locked):

Think about it, in a way, because of the emergence of concurrency issues, so lead to repeated recharge the account, then can we use locking way to solve it? Of course it is possible

Process is as follows:

  1. Alipay payment successfully received callback request
  2. Call java in the lock,
  3. According trade_no out_trade_no query the database and order information, the order is being processed
  4. If the order is processed directly back, if not treated, continue down
  5. Enable local affairs
  6. The local system to the user to add money
  7. The order status is set to success
  8. Submit local transaction
  9. Lock lock release

Thinking:

Such seems to have no problem, is not it? In fact not the case, think about it, if we just deployed an application, this is no problem, but if we do load balancing applications, the deployment of multiple machines, this will not be a problem, after the pullback over Alipay, through load balancing services, the request is assigned to a different machine, not to die in this way is it? At this time, the locking process is equivalent to no way a result will appear.

Policy think nginx load balancing requests can be set to request the same ip's are on the same server, with this configuration, if you can solve the problem?

Three ways :( pessimistic lock mode)

Use database pessimistic locking way, in fact, with the way like two locking way, but rely on the database to achieve, the database is to use pessimistic locking for update to achieve, as follows:

  1. Alipay payment received successful request.
  2. Open Local Affairs
  3. Query order information and add pessimistic locking (select * from t_order where order_id = trade_no for update;)
  4. Determining whether the order has been processed, if the processing directly returns, if untreated, continues down
  5. Local user account to add money to the system
  6. The order status has been modified to handle
  7. Submit local transaction

Thinking:

The way it is mainly shipped with a database for update, for update on to explain:

1. When thread A executed for update, the data will lock the current record, when other threads execute this line of code, thread A releases the lock will wait before they can acquire the lock, continue to follow-up operation.
2. When things submission, for update locks acquired will be automatically released.

If our business is more complex system logic, then, in the concurrent circumstances, lead to the back of the thread is waiting invalid state, are waiting to acquire a lock for update pessimistic, this is not conducive concurrent operating system

Four ways: optimistic locking

Use optimistic locking database to achieve, as follows:

      1. received Alipay payment success callback request

      2. Order Information query (select * from t_order where order_id = trade_no;)

      3. To determine whether the order information has been processed, if the return has been processed directly, if not handled continues

      4. Open the Local Affairs

      5. local user account to add money to the system

      6. Similar to the following pseudo-code is successfully modified order status

update t_order set status = 1 where order_id = trade_no where status = 0;
//上面的update操作会返回影响的行数num
if(num==1){
 //表示更新成功
 提交事务;
}else{
 //表示更新失败
 回滚事务;
}

      Thinking:

update t_order set status = 1 where order_id = trade_no where status = 0;

Relying on optimistic locking is implemented, the implementation of this sql, if there are multiple threads colleagues reach this code, the internal database will ensure that update the same record will line up, will eventually only one update is successful, other unsuccessful return num is 0, then commit or rollback operation according num

Way five: unique constraint

The only constraint is dependent on the database to achieve, in fact, very simple, as follows:

First, we need to build a table, t_uq_dipose, this table inside it contains a type field of business, type of business and the unique order number in the system, when operational, the first query the table there is no corresponding data If not, continue, if if there is a direct return

First create a table:

TABLE `t_uq_dipose` the CREATE (
  ` id` BIGINT (20 is) the AUTO_INCREMENT the NOT NULL,
  `ref_type` VARCHAR (32) the NOT NULL the DEFAULT '' the COMMENT 'associated object type',
  ` ref_id` VARCHAR (64) the NOT NULL the DEFAULT '' the COMMENT ' associated object ID ',
  a PRIMARY KEY ( `id`),
  uNIQUE KEY` uq_1` (ref_type` `,` ref_id`) the COMMENT' ensure the uniqueness of service '
);

You can see, we have built a unique constraint, so ref_type and ref_id can ensure that data inserted into the table is absolutely unique.

Process is as follows:

  1. Alipay successfully receive callback pay
  2. T_uq_dipose table query can determine whether the order has been processed
  3. Determining whether the order has been processed, if processed directly back, if untreated, continue down
  4. Open Local Affairs
  5. To the local system user to add money
  6. The order status changed to success
  7. T_uq_dipose insert data into a table, insert the successful submission of local affairs, the insertion is not successful, roll back the local transaction.

to sum up

Of the common way to achieve power, which are: pessimistic locking, optimistic locking, the only constraint

In several ways, according to the optimal schedule: optimistic locking> The only constraint> pessimistic locking

 

 

Published 11 original articles · won praise 4 · Views 5497

Guess you like

Origin blog.csdn.net/qq_34776233/article/details/101155742