How to deal with a transaction encountering a third-party API request

1. Usage scenario:

1. Function realization requires multiple database operations

2. The method includes requesting a third-party API interface

2. Scenarios encountered in the use of third-party APIs

(1) The success or failure of the third-party API does not affect the progress of the main business, such as message push

Processing method: Extract the message push method and perform asynchronous processing to avoid request errors affecting the main business process;

Note: The asynchronous method needs to be extracted into another class, otherwise @Async will not take effect

img

img

(2) The third-party API is inseparable from the main business (such as employee transfer, employee resignation related API)

Handle display:

① Request the API, and perform business processing (database operations) according to the results returned by the API

② Perform database operations first, and then request third-party APIs

Thinking: What is the difference between ① and ②?


① Request the API, and perform business processing (database operations) according to the results returned by the API

Problem: If the API interface returns an error, there is no need to perform subsequent business logic processing and terminate directly

但是,如果API请求通过, 后续业务逻辑执行一旦出错,进行回滚, API无法回滚 , 导致事务不一致
例如员工离职,已从钉钉架构中移除员工,但是数据库状态回滚为正常状态,造成数据不一致
② Perform database operations first, and then request third-party APIs

Advantages: When an error occurs when requesting a third-party API, the database data can be rolled back;

It can be concluded that the first order (API first, then modify the library) is fatally flawed, and this processing method is prohibited in the code!

2. What should I do when I encounter an API?

1. API request commonality

(1), clear success

The meaning of definite success is obvious, and this is also the most commonly used success situation. When the third party returns a 200 status code or OK to you, it can be definite success.

Possible problems: the request time is too long

(2), clear failure

The meaning of clear success is obvious, and this is also the most common failure situation we use. When a third party returns a non-200 status code or OK to you, it can be a clear failure, and you can handle the rollback.

Possible problems: the request time is too long

(3), the result is unknown

When your request is sent, because the third-party processing time is too long (maybe their server has a problem, or the business is complicated), the connection is directly disconnected, and no one knows whether the processing has been completed on his side.

Possible problem: timeout condition

2. Problems with API requests

(1), the API request timed out and cannot be processed

The request API timed out, the program judged that the modification failed, and the transaction was rolled back, but the API method was actually still being executed, resulting in data inconsistency.

(2), the API request time is too long, and the library is occupied for a long time

Although the API request is successful, it takes 20s to complete the processing, because the above operations on our own library are already in the transaction and have not been submitted, so our operations will be locked for 20s. When there are too many, it will generate question.

3. Solution:

Solution 1: Solve the timeout problem

If there is a condition - the caller and the callee are well coordinated, and the caller can be provided with a callback or polling query interface

Callback: For example, if the super store manager calls Qianyun, Qianyun provides a callback interface for the super store manager and returns the processing result

Polling: The super store manager regularly requests Qianyun to get the result

What are the benefits of doing this?

Through the callback or polling function provided by the callee, we can clearly know whether our call is completely successful or completely failed, and there will be no ambiguity. It guarantees the certainty of the third-party API results and builds the premise for the consistency of transactions.

downside of doing this

There is no disadvantage in doing this, and formal programs will be provided. The only disadvantage is that irregular ones may not be provided. This also requires us to provide callbacks or polling for others according to the importance of the business when we provide business interfaces for others. method.

Solution 2: Solve the library occupation problem

Enable programmatic transactions to wrap operations on database modifications

    // 方法上不加事务
    public SimpleMessage testA() {
    
    
        // 进行校验参数,一些查询
        Select ***

        // 开启事务,进行一些数据库修改操作
        transactionTemplate.execute(status -> {
    
    
            update ***
            update ***

            return null;
        });
        // 进行第三方API请求
        httpUtils.post***;
        return new SimpleMessage(ErrorCodeEnum.OK);
    }

img

Instructions

What are the benefits of doing this?

The multiple operation data of the own library has been executed, the transaction has been submitted and released, and the API request is not in the transaction, and the own library will not be locked.

downside of doing this

Although the library is not occupied, if the third-party request fails, the transaction will still be inconsistent. Moreover, the timeout problem still cannot be solved. There may be a timeout situation, and the result is unknown, resulting in transaction inconsistency.

Solution 3: Improvement on the basis of ① and ②

On the basis of scheme ②, restore the failure situation (using programmatic transactions)

Use callback/polling processing on the basis of scheme ①

    // 方法上不加事务
    public SimpleMessage testA() {
    
    
        // 进行校验参数,一些查询
        Select ***

        // 开启事务,进行一些数据库修改操作
        transactionTemplate.execute(status -> {
    
    
            update num = 2 where ***
            update ***

            return null;
        });
        // 进行第三方API请求
        httpUtils.post***
        // 根据API请求返回结果, 如果失败则对数据进行回退操作
        // 开启事务,进行数据恢复操作
        transactionTemplate.execute(status -> {
    
    
            update num = 1 where ***
            update ***
            return null;
        });
        return new SimpleMessage(ErrorCodeEnum.OK);
    }

hint

When the TransactionTemplate is executed, no matter whether a checked exception (Exception) or an unchecked exception (RuntimeException) occurs, a rollback operation will be performed, so there is no need to worry about major bugs caused by non-committing transactions.

the benefits of doing this

1. The library is prevented from being occupied, and manual rollback can be performed after a failed result is obtained.

downside of doing this

1. It is more troublesome to write

2. If the third party does not provide callback or polling, there is still no way to guarantee transaction consistency, so the third party is very important. If it is provided by a third party, it will be a perfect solution if it is used with the solution ①. If the third party does not provide it, there will be no perfect solution, which indirectly shows that this business is not very important and developers are very lazy.

Guess you like

Origin blog.csdn.net/qq_43842093/article/details/130632426