RocketMQ Distributed Transaction Solutions

Foreword

After the system becomes complex, distributed, service and other micro-architecture technology, it is necessary to consider the application in the system. In particular, the large amount of data, the need for a database split .

Such as: registration of user data, the volume, and you need to consider sub-library sub-table

Once the database has been split, then a lot of headaches, one of which is a transaction problem . Then we look at the problem is how to appear in?

Scenes

 

 

Figure on a first-come,

After splitting the data, it is similar to the above schema

We figure above example, the user took data of users once tens of millions on the need for sub-library sub-table ; FIG on three points on the database, each library to ensure high availability.

This architecture design, the transaction will encounter a problem, we look at the specific business scenario: A user transfer 100 yuan to user B, this business is relatively simple, we have to analyze which specific steps :

1, the user A's account to deduct 100 yuan 2, then the user B's account additional 100

 

 

The logic is simple, the pseudocode

The code is relatively clear, I feel there is no problem, then we have to analyze the problem lie?

problem

We see in the transfer business, there are two steps, a user A is deducting money operation, a user is operating B plus money

If you are in the same database, you can ensure that this two-step operation, at the same time either succeed or not succeed at the same time. This ensures that the transfer of data consistency.

However, if the data of the user A cluster A, B, user B in the cluster do? Because they are not the same transaction in; A user charge as successful, but user B plus the money failed; it would pit, incomplete data up.

This problem is similar to the micro-service architecture will be more , because all the services are independent modules, all long-distance calls , no law in the same transaction, the transaction will encounter problems.

How to solve it? There are some online programs, such as: two-phase commit, TCC, etc., there is commonly eventual consistency scheme. Today'll tell you about how to use the messaging middleware to solve . Then we put the plan to adjust the look, add messaging middleware , and see how optimization.

Messaging middleware solutions

The figure is the use of messaging middleware way, the deduction of asynchronous traffic, and money business , after a successful charge, sends a "debit success message" to the messaging middleware ; add money business Subscribe "debit success message" , then user B to add money

The system knows how to user B plus money? Is the message body which contains the source account and the destination account ID, and the amount of money

This time maybe little friends will ask, should also be a problem, right: Scene One: After the first charge message

The first charge and then send a message, send the message in case of failure, that user B would not be able to add money

That the order of adjustments Scene 2: first message, after deduction

Debit success message is sent successfully , but the user A failed charge , you can add money to subscribe to the news service, the user B plus money

We should see a problem, which is not guaranteed debit and send messages, and success or failure at the same time ; resulting in inconsistent data.

RocketMQ services program

Because of the above problems, RocketMq the messaging middleware message is divided into two stages : Prepared phase and validation phase Prepared stage (preliminary stage)

The stage is mainly to send a message to rocketmq, but the message is only stored in commitlog in , but consumeQueue not visible, is the consumer side (subscription ends) can not see this message .

commit / rollback phase (validation phase)

The main stage is the prepared message is saved to consumeQueue in that so that consumers can see the end of this message , that can consume the message .

 

 

We use the diagram to illustrate the next:

The entire process :

1, before deductions, to send a message ready
2, after sending the message successfully prepare, execute local debit transactions
3, after deduction successful, then send a confirmation message
4, the message end (plus money business) you can see a confirmation message, consumption of this message, the more money

Confirmation message Description

NOTE: The above confirmation message may commit messages can be consumed subscribers; can also be Rollback news, namely the implementation of the local debit transaction fails to submit rollback message, the message is deleted the preparation, subscribers can not consume

Let's analyze abnormal scenario :

Abnormal 1: If you send a message preparation fails, the following procedure will not go; this is normal and
abnormal 2:
If you send a message preliminary success, but the implementation of a local transaction fails; this is not a problem, because this message is not ready to be consumed end Subscribe to the consumer end of the business will not be executed.
Abnormal 3:
If you send a message preparation succeeds, the local transaction is successful, but failed to send an acknowledgment message; this is a problem, because the user A debit successful, but add money business is not subscribed to the confirmation message, you can not add money. Here there has been inconsistent data.

That RocketMq is how to solve it?

Check back RocketMQ

image

How RocketMq solve the above problem, the core idea is to check back [state] , which is RocketMq regularly traverse commitlog in preparation message.

Because provisioning message will eventually become the message Rollback or commit message , so the message is ready to traverse back to check the implementation status of the local business, if found without performing a successful local business on rollBack , if executed successfully sends commit messages.

The above anomaly 3, ready to send the message succeeds, the local debit transaction is successful, but failed to send an acknowledgment message; because RocketMq will conduct a preliminary investigation back to the message , check back in after the discovery business has been successfully charged , and then reissue "to commit confirmation message " ; so add money to the business can subscribe to this message up.

In fact, this idea also solves the abnormal 2, because there is no local transaction is executed successfully, RocketMQ back to check business, found no successful execution, RollBack will be sent a confirmation message, the message is deleted .

Check back judge whether business success

Small partners in check back in business, how to determine whether the local transaction is executed successfully ?

If the local transaction executes a lot of tables, it is not that we want those tables should be carried out to determine whether it successfully ? This is not too much trouble, and business and are coupling.

Is there a better way? Is to design a Transaction table , the business table and Transaction binding in the same local transaction , if the transaction is successful debit local, Transaction records should have been the TransactionId state is "Completed." When RocketMq back to check, just check the corresponding whether TransactionId status is 'Completed' like , without worrying about the specific business data.



Author: Lost er
link: https: //www.jianshu.com/p/286cac4625b6
Source: Jane books
are copyrighted by the author. Commercial reprint please contact the author authorized, non-commercial reprint please indicate the source.

Published 18 original articles · won praise 588 · Views 1.03 million +

Guess you like

Origin blog.csdn.net/hellozhxy/article/details/105053302