Will you understand distributed transactions in this way?

Distributed transactions mainly solve the problem of distributed consistency. After all, the distributed operation of data leads to the fact that only local transactions cannot guarantee the originality. Different from the stand-alone version of the transaction, the single machine packs multiple commands into one unified processing, and the distributed transaction packs the commands executed on multiple machines into one command for unified processing.

Common distributed transaction scenarios#

Distributed transactions are actually by our side, you have been using it, but you have not paid attention to it.

Transfer

Deduct the balance of your account and increase the balance of someone else’s account. If you only deduct your money and others don’t increase it, it’s a failure; if you don’t deduct your money, others also increase the bank’s loss.

Place an order/deduct inventory

This is a very common scenario in the e-commerce system. The user placed an order successfully, but the store did not receive the order and did not ship; the user cancelled the order, but the store saw the order and delivered the goods.

Sub-database and sub-table scenario

When our data volume is large, we may deploy many independent databases, but one of your logic may operate on many database tables at the same time. At this time, how to ensure that all operations succeed or fail.

Distributed system call problem

The separation of microservices allows each system to perform its duties, but it also brings a lot of pain. An operation may be accompanied by a lot of external requests. If an external system hangs up, does the previous operation need to be rolled back? .

In response to the above problems, the four major characteristics of the database we have learned before: ACID seems to be very difficult to achieve here. In the case of a single machine, you can also control the data through the lock and log mechanism. What about the distributed scenario? Realization? Under different distributed application architectures, the issues to be considered for implementing a distributed transaction are not exactly the same, such as the coordination of multiple resources and the cross-service propagation of transactions. The implementation mechanism is also complex and changeable. Although there are so many engineering details to consider, the core of distributed transactions is its ACID feature, but this ACID changes the scene.

Distributed Theory#

CAP theorem

The traditional ACID model certainly cannot solve the challenges in a distributed environment. Based on this, Professor Eric Brewer of the University of California at Berkeley put forward the CAP theorem. He pointed out that modern web services cannot satisfy the following three attributes at the same time:

  • Consistency: All clients can return the latest operation.
  • Availability (Availability): Non-faulty nodes return a reasonable response within a reasonable time (not an error and timeout response).
  • Partition tolerance: Even if a single component cannot be used, the operation can still be completed.

There are three directions behind the understanding of consistency:

  • Strong consistency: The most recently written data of a certain data can be read at any time. All processes in the system, see the order of operations, are consistent with the order under the global clock. In short, at any time, the data in all nodes is the same.
  • Weak consistency: After the data is updated, if you can tolerate that the subsequent access can only be accessed partially or completely, it is weak consistency.
  • Eventually consistent: There is no guarantee that the same piece of data on any node at any time is the same, but with the migration of time, the same piece of data on different nodes will always change in different directions. Simply put, after a period of time, the data between nodes will eventually reach a consistent state.

With regard to the different understanding of consistency, the implementation of CAP theory will be different later.

In addition, Professor Eric Brewer pointed out that modern WEB services cannot satisfy these three attributes at the same time. He said that they cannot satisfy them at the same time. Why is that?

If there is no copy in a distributed system, then strong consistency and availability must be satisfied, but if this data goes down, the availability cannot be guaranteed.

If a system satisfies AP, then consistency cannot be guaranteed. So the essence of the CAP principle is either AP, CP, or AC, but there is no CAP.

BASE theorem

Based on the CAP mentioned earlier, we can't meet the CAP at the same time anyway. The highest purpose of designing the system is to make him run without making mistakes. Then, is it possible not to require strong consistency, and finally make him consistent? So the BASE theorem was put forward later:

  • Basically Available
  • Soft state
  • Eventually consistent (eventually consistent)

Based on the complexity of the current large-scale distributed system, we cannot guarantee that the service will always reach 999, so whether it is possible to choose, the core service reaches 999, and the non-core service is allowed to be linked to preserve the core service. In addition, temporary inconsistencies in the system are allowed during the downtime of non-core services, but this inconsistency does not affect the use of the core functions of the system.

Eventually the system is restored, and all services repair the data together, and finally reach a consistent state.

The industry usually refers to transactions that strictly follow ACID as rigid transactions , and transactions based on the BASE idea are called flexible transactions . Flexible transactions do not completely abandon ACID, but just relax the consistency requirements: the consistency after the transaction is completed is strictly followed, and the consistency in the transaction can be appropriately relaxed.

Recommended viewing: Portal

Common distributed transaction implementation scheme#

The distributed transaction implementation scheme distinguishes rigid transactions and flexible transactions from the type. Rigid transaction: usually no business transformation, strong consistency, native support for rollback/isolation, low concurrency, suitable for short transactions. Flexible transaction: business transformation, final consistency, compensation interface, resource locking interface, high concurrency, suitable for long transactions.

  • Rigid transaction: XA protocol (2PC, JTA, JTS), 3PC
  • Flexible transaction: TCC/FMT, Saga (state machine mode, Aop mode), local transaction message, message transaction (semi-message), most effort notification transaction

Two-phase commit (XA)

Like local transactions, a two-phase commit scheme can also be used in distributed transaction scenarios. The full name of XA is eXtended Architecture, which is a distributed transaction protocol that guarantees strong consistency through a two-phase commit protocol.

The XA specification defines a distributed transaction processing model, which contains four core roles:

  • RM (Resource Managers): Resource Manager, which provides operation and management interfaces for data resources to ensure data consistency and integrity. The most representative is the database management system. Of course, some file systems and MQ systems can also be regarded as RM.
  • TM (Transaction Managers): Transaction Manager, is the role of a coordinator to coordinate the behavior of all RMs associated with cross-database transactions.
  • AP (Application Program): The application program calls the RM interface according to business rules to complete the changes to the business model data. When the data changes involve multiple RMs and transactions must be guaranteed, AP will define the boundaries of the transactions through TM, TM Responsible for coordinating each RM participating in the transaction to complete a global transaction together.
  • CRMs (Communication Resource Managers): Mainly used for the spread of cross-service transactions.

Will you understand distributed transactions in this way?

 

The approximate two processes of the XA protocol are:

  1. The first stage (prepare): The transaction manager initiates a request to all local resource managers to ask whether it is in the ready state, and all participants send feedback on whether the transaction can be successful or not to the coordinator;
  2. The second stage (commit/rollback): The transaction manager notifies all local resource managers based on the feedback of all local resource managers, and commits or rolls back on all branches in unison.

How does the XA protocol satisfy ACID?

Needless to say, the originality and durability, let's look at isolation and consistency.

Isolation

The XA protocol does not describe how to achieve the isolation of distributed transactions, but the XA protocol requires each resource manager to implement local transactions, which means that the isolation of distributed transactions based on the XA protocol is determined by each resource manager The isolation of local transactions is guaranteed. When all sub-transactions of a distributed transaction are isolated, then the distributed transaction naturally achieves isolation.

consistency

Consistency in a stand-alone environment is to ensure that the current server data is consistent. After the transaction is executed, the data is finally consistent, and the intermediate state of the transaction execution process under different isolation levels cannot be observed by other transactions.

After the transaction is executed, it is a good guarantee that it will eventually be consistent, but in the RR isolation level, how can the intermediate state of an uncommitted transaction be achieved in a distributed situation? MySQL on a single machine provides an MVCC mechanism, which uses multi-version control to handle it. Can a distributed transaction scenario also provide such a mechanism? The XA protocol does not define how to implement global snapshots. A basic idea is to use a centralized or logically monotonically increasing thing to control the generation of global snapshots, which will be obtained once for each transaction or each SQL execution to achieve different isolation Consistency under the level. Of course, development is still quite difficult.

Existing problems:

  • Synchronous blocking: When the transaction participants occupy public resources, one of them occupies the resources, the other transaction participants can only block and wait for the resource to be released and are in a blocked state.
  • Single point of failure: Once the transaction manager fails, the entire system is unavailable.
  • Data inconsistency: In phase 2, if the transaction manager only sends part of the commit message, and the network is abnormal at this time, then only some participants receive the commit message, that is to say, only some participants submit the transaction, making the system data inconsistent.
  • Uncertainty: After the transaction manager sends a commit, and only one participant receives the commit at this time, when the participant and the transaction manager are down at the same time, the re-elected transaction manager cannot determine whether the message is submitted success.

Generally speaking, the XA solution is simple to implement, but the problems that arise cannot be guaranteed if it is placed in a scenario with strict data consistency requirements. In addition, the single point of the transaction manager will bring hidden dangers, and the synchronous blocking model also leads to weak concurrency.

TCC

The concept of TCC (Try-Confirm-Cancel) was first proposed by Pat Helland in a paper entitled "Life beyond Distributed Transactions: an Apostate's Opinion" published in 2007. Compared with the XA described above, the TCC transaction mechanism solves several shortcomings:

  1. The single point of the coordinator is solved, and this business activity is initiated and completed by the main business party. The business activity manager has also become multipoint, introducing clusters.
  2. Synchronous blocking: Introduce timeout, compensate after timeout, and will not lock the entire resource, transform the resource into business logic form, and reduce the granularity.
  3. Data consistency, after having a compensation mechanism, the business activity manager controls the consistency.

TCC is actually the compensation mechanism adopted. Its core idea is: For each operation, a corresponding confirmation and compensation (revocation) operation must be registered. The TCC model is completely handed over to the business to implement, and each sub-business needs to implement the Try-Confirm-Cancel three interfaces, which is intrusive to the business and the resource lock is left to the business side.

  • Try stage: Try to execute, complete all business checks (consistency), and reserve necessary business resources (quasi-isolation).
  • Confirm phase: Confirm that the actual execution of the business is performed, without any business checks, and only use the business resources reserved in the Try phase, and the Confirm operation satisfies the idempotence. Idempotent design is required, and a retry is required after Confirm fails.
  • Cancel phase: Cancel the execution and release the business resources reserved in the Try phase. The Cancel operation satisfies idempotence. The exceptions in the Cancel phase are basically the same as those in the Confirm phase.

Will you understand distributed transactions in this way?

 

A complete business activity consists of a main business service and several sub-business services:

  1. The main business service is responsible for initiating and completing the entire business activity;
  2. Business services provide TCC-type business operations;
  3. The business activity manager controls the consistency of business activities. It registers the operations in the business activity and confirms the Confirm operation of all TCC-type operations when the business activity is submitted, and calls the Cancel operation of all TCC-type operations when the business activity is cancelled.

For example, a transfer operation:

  1. First freeze the transferor's wallet during the Try phase.
  2. In the Confirm phase, call the transfer interface to operate the transfer, and unfreeze the transfer after successful transfer.
  3. If the Confirm phase is successful, the transfer is successful, otherwise the transfer failure confirmation logic is executed.

Based on TCC to implement distributed transactions, the logic that can be implemented with only one interface is split into three interfaces: Try, Confirm, and Cancel, so the code implementation complexity is relatively high, and a lot of compensation mechanism code needs to be written in the business .

TCC divides the transaction commit into two stages, Try is the first stage, Confirm and Cancel are two parallel branches of the second stage, choose one of the two. The stage division is very similar to 2PC. Can we say that TCC is a 2PC or a variant of 2PC?

Compared with the XA transaction model, there are still some differences between TCC's two-phase commit and XA:

  1. The operation object of 2PC lies in the resource layer and is unaware of developers; while the operation of TCC lies in the business layer, which has high development costs.
  2. 2PC is an overall long transaction and also a rigid transaction; while TCC is a group of local short transactions, a flexible transaction.
  3. 2PC's Prepare (voting stage) conducted operation voting; while TCC's Try did not prepare for voting, and directly combined resource operation and preparation capabilities.
  4. 2PC is a global lock resource, all participants block interaction and wait for TM notification; while TCC's resource lock lies in the Try operation, and the business party can flexibly choose the lock granularity of business resources.

Local message table#

The local message table was originally mentioned by Dan Pritchett, an eBay architect, in a paper "Base: An Acid Alternative" (https://queue.acm.org/detail.cfm?id=1394128) explaining the principle of BASE. The industry currently uses this scheme more, and its core idea is to split distributed transactions into local transactions for processing.

The solution is to create an additional transaction message table on the active initiator of the transaction. The transaction initiator processes the business and records the transaction message in a local transaction, polls the data in the transaction message table to send transaction messages, and the passive party consumes the transaction message table based on the message middleware. Business.

Based on the local message table solution, each transaction initiator needs to create an additional transaction message record table to record the occurrence and processing status of distributed transaction messages.

Will you understand distributed transactions in this way?

 

The transaction initiator needs to save the current transaction in the message table after processing the business logic, then send the message to the message middleware, and set the status of the message to "sending".

What if the message is lost during delivery? The transaction initiator can set a timed task to actively scan the message whose status is "sending" and re-deliver it. Only when the message is consumed by the business party and the result of successful consumption is returned, the success is confirmed and the message status is changed to "sent".

Here, a message may be repeatedly sent due to network abnormalities or sending abnormalities, so the receiver is required to be idempotent and allow repeated consumption.

The advantage of this scheme is that the scheme is simple, the cost is low, and the implementation is not complicated.

But there are many disadvantages. For example, the delay through the message is not easy to control; the local message table is coupled with the business and it is not universal; the local message table is implemented based on the database, which has certain bottlenecks.

Transaction message#

The mode of the local message table mentioned above cannot support the consistency of local transaction execution and message sending. If transactions can be added to the two operations of local transaction execution and message sending, it would not be perfect.

Based on this idea, the state of storing the message in MQ is the truth. The message producer first sends the message to MQ. At this time, the message state is "to be confirmed", and then the producer executes the local transaction. If the execution is successful, it sends it to MQ. The message tells him to change the message status to "to be sent" and send the message, and delete the message if the execution fails.

This ensures the consistency of local transactions and message delivery.

Will you understand distributed transactions in this way?

 

  1. First, the transaction initiator first sends a pre-read message to MQ. The difference between this message and the ordinary message is that it is only visible to MQ and will not propagate downward.
  2. After MQ receives the message, it first persists, then a new message with the status to be sent will be added to the storage, and then the transaction initiator will return a processed ACK; the transaction initiator will start to execute the local transaction after receiving the processed ACK .
  3. The initiator will decide whether the pre-read message should continue or roll back based on the execution status of the local transaction. In addition, MQ should also support its own reverse investigation to solve the abnormal situation. If the initiator's local transaction has been executed and sent a message to MQ, but the message is lost due to network reasons, how to solve it. So this counter-check mechanism is very important.
  4. After the local transaction is executed successfully, MQ also receives a successful notification, then updates the message status to sendable, and then pushes the message to downstream consumers. At this time, the consumer can handle their own local transactions.

Note : Since MQ usually guarantees that the message can be delivered successfully, if the business does not return the ACK result in time, it may cause the repeated message delivery problem of MQ. Therefore, for the solution of message final consistency, message consumers must support idempotent consumption of messages, and cannot cause repeated consumption of the same message.

SAGA Transaction Model#

What is Saga? Saga is defined as "Long Lived Transaction" (Long Lived Transaction, hereinafter referred to as LLT). He is a concept proposed by Professor HECTOR GARCIA-MOLINA of Princeton University in a 1987 paper on distributed databases.

Long Lived is not clear in the literal sense. How long does Long mean? Is the transaction duration an hour, a day, or even a week? Actually neither, the time span is not important. What is important? The key is multiple "transactions" across systems. Saga is often composed of multiple external transactions, and multiple external system message interactions are required to migrate the overall transaction from the beginning to the end state. This is similar to what we have seen before. The short transaction of a database is not the same. For example, a travel order is composed of three sub-orders for air tickets, hotels, and car rentals, all of which require external confirmation. Without any step, the trip cannot be made. This is a typical LLT.

It seems that the definition of Sage is no different from other distributed transactions. Isn't a distributed transaction that multiple different sub-transactions form a whole? Let's take a look at the compensation mechanism:

Each local transaction has a corresponding execution module and compensation module. When any local transaction in the Sage transaction fails, it can be restored by calling the corresponding compensation method of the related transaction to achieve the ultimate consistency of the transaction.

The Saga model splits a distributed transaction into multiple local transactions. Each local transaction has a corresponding execution module and compensation module (corresponding to Confirm and Cancel in TCC). When any local transaction in the Saga transaction fails, The previous transaction can be restored by calling the relevant compensation method to achieve the final consistency of the transaction.

Since there is no Prepare phase in the Saga model, isolation between transactions cannot be guaranteed. When multiple Saga transactions operate on the same resource, problems such as update loss and dirty data reading will occur. At this time, concurrency needs to be controlled at the business layer, for example:

  • Lock at the application level;
  • Pre-freeze resources at the application level.

Saga recovery method

Saga supports forward and backward recovery:

  • Backward recovery: Compensation for all completed transactions, if any transaction fails;
  • Forward recovery: Retry failed transactions, assuming that each sub-transaction will eventually succeed.

Although both Saga and TCC are compensation transactions, they are different due to the different commit phases:

  • Saga does not directly Commit the Try behavior, so it will leave traces of the original transaction operation. Cancel is an imperfect compensation and needs to consider the impact on the business. TCC Cancel is a perfectly compensated Rollback. The compensation operation will completely clean up the original transaction operation before, and the user will not perceive the status information before the transaction is cancelled.
  • Saga's compensation operation can usually be executed asynchronously, and TCC's Cancel and Confirm can follow up whether it needs to be asynchronous.
  • Saga is less intrusive to the business, and only needs to provide a reverse operation of Cancel; while TCC needs to carry out a global process transformation for the business.
  • The minimum number of TCC communications is 2n, and Saga is n (n=the number of sub-transactions).

Because the compensation mechanism is also used, the service must be required to maintain idempotence. If the service call times out, idempotence must be used to avoid problems caused by multiple requests.

Satisfaction of transaction characteristics:

Atomicity: The Saga coordinator guarantees that the entire transaction is either executed successfully or all rolled back.

Consistency: Sage guarantees eventual consistency.

Persistence: Saga splits the overall transaction into independent local transactions, so persistence is well achieved in local transactions.

But the isolation Saga cannot be realized, because the large transaction is split into multiple small transactions, and the timing of each transaction is different, it is difficult to ensure that the small transaction that has been committed is not visible to others.

The industry currently provides two types of Saga implementations:

  • One is the realization of centralized coordination. The centralized coordination method is to track all the invocations of Saga subtasks through a Saga object, manage it, and track whether the entire transaction should be submitted or compensated. The disadvantage of this approach is that this coordination approach must be coupled with the first Saga transaction, that is, coupled with the business.
  • One is the distributed implementation. Distributed coordination can certainly avoid the problem of coupling. There are also many distributed implementation solutions, such as through the event mechanism, all transactions on a Saga transaction chain are subscribed to the same event, and if it fails, it can be rolled back through the event message corresponding to the failure. The benefits of this approach are definitely obvious, but there will be another problem. The processing of multiple events must be highly concurrent, so will there be some circular dependencies due to multiple event processing related issues The problem.

Introduction to Open Source Distributed Transaction Framework#

Seat

Seata (Simple Extensible Autonomous Transaction Architecture) is a distributed transaction solution jointly open sourced by Ant Financial and Alibaba in January 2019.

Seata will have 4 distributed transaction solutions, namely AT mode, TCC mode, Saga mode and XA mode.

Will you understand distributed transactions in this way?

 

XA mode

XA mode is another non-intrusive distributed transaction solution that Seata will open source. Any database that implements the XA protocol can be used as a resource to participate in distributed transactions. At present, mainstream databases, such as MySql, Oracle, DB2, and Oceanbase All support the XA protocol.

The XA protocol has a series of instructions, corresponding to the first and second stages of operation. "Xa start" and "xa end" are used to start and end XA transactions; "xa prepare" is used to pre-commit XA transactions, corresponding to one stage of preparation; "xa commit" and "xa rollback" are used to commit and roll back XA transactions , Corresponding to the two-phase commit and rollback.

In XA mode, every XA transaction is a transaction participant. After the distributed transaction is started, first execute "xa start", "business SQL", "xa end" and "xa prepare" in the first stage to complete the execution and pre-commit of the XA transaction; in the second stage, execute "xa commit" if submitted , If it is a rollback, execute "xa rollback". This will ensure that all XA transactions are committed or rolled back.

Will you understand distributed transactions in this way?

 

In XA mode, users only need to pay attention to their own "business SQL", and the Seata framework will automatically generate one-phase and two-phase operations; the implementation of XA mode is as follows:

Will you understand distributed transactions in this way?

 

  • The first stage:

In the first stage of the XA mode, Seata will intercept the "business SQL", start the XA transaction ("xa start") before the "business SQL", then execute the "business SQL", end the XA transaction "xa end", and finally pre-commit XA Transaction ("xa prepare"), which completes the preparation of "business SQL".

  • Two-stage submission:

Execute the "xa commit" instruction to submit the XA transaction. At this time, the "business SQL" is actually submitted to the database.

  • Two-stage rollback:

Execute the "xa rollback" instruction to roll back the XA transaction, complete the "business SQL" rollback, and release the database lock resources.

In XA mode, users only need to pay attention to "business SQL", Seata will automatically generate one-phase, two-phase commit and two-phase rollback operations. XA mode, like AT mode, is a non-intrusive solution to the business; but unlike AT mode, XA mode delegates snapshot data and row locks to the database through XA instructions, so that the XA mode achieves more Lightweight.

AT mode

AT mode is a non-intrusive distributed transaction solution. In the AT mode, users only need to pay attention to their own "business SQL". The user's "business SQL" is the first stage, and the Seata framework will automatically generate the two-stage commit and rollback operations of the transaction.

Will you understand distributed transactions in this way?

 

One-phase, two-phase commit and rollback of AT mode

All are automatically generated by the Seata framework. Users only need to write "business SQL" to easily access distributed transactions. The AT mode is a distributed transaction solution without any intrusion to the business.

TCC mode

In March 2019, Seata open sourced the TCC model, which was contributed by Ant Financial. The TCC mode requires users to implement the three operations Try, Confirm and Cancel according to their own business scenarios; the transaction initiator executes the Try method in the first phase, submits the Confirm method in the second phase, and rolls back the Cancel method in the second phase.

Will you understand distributed transactions in this way?

 

Three methods of TCC are described:

  • Try: detection and reservation of resources;
  • Confirm: Submit the executed business operation; if Try is successful, Confirm must be successful;
  • Cancel: The reserved resources are released.

The most important thing for users to access the TCC mode is to consider how to split the business model into two phases and implement it into the three methods of TCC, and ensure that the Try is successful and the Confirm will be successful. Compared with AT mode, TCC mode is somewhat intrusive to business codes, but TCC mode does not have the global row lock of AT mode, and TCC performance is much higher than AT mode.

Saga mode

Saga mode is Seata's upcoming open source long-term transaction solution, which will be mainly contributed by Ant Financial. In the Saga mode, there are multiple participants in a distributed transaction, and each participant is a positive compensation service, requiring users to implement their forward operations and reverse rollback operations according to business scenarios.

During the execution of a distributed transaction, the forward operations of each participant are executed in turn. If all forward operations are executed successfully, the distributed transaction is committed. If any forward operation fails, the distributed transaction will go back to perform the reverse rollback operation of the previous participants, roll back the committed participants, and return the distributed transaction to the initial state.

Will you understand distributed transactions in this way?

 

Distributed transactions in Saga mode are usually event-driven, and each participant is executed asynchronously. Saga mode is a long transaction solution.

ServiceComb

ServiceComb is Huawei's open source microservice framework, which has been upgraded to the top Apache project. To be precise, it is not a purely distributed transaction framework but a microservice framework. The initial version is the Go language and later supports Java.

ServiceComb consists of 3 sub-projects:

  • java-chassis: service governance
  • service-center: service registration
  • saga: Distributed transaction solution

From the name, it is obviously a flexible transaction solution developed based on the Saga model. The Saga system is divided into two parts: Alpha and Omega. Alpha is an independent service, acting as a transaction coordinator. As a development component, Omega runs with business processes.

Will you understand distributed transactions in this way?

 

Omega will inject relevant processing modules into the application in a way of aspect programming. There are modules for intercepting requests to help us build the context of distributed transaction calls. At the same time, the related preparation operations of the transaction are processed at the initial stage of transaction processing, such as creating a Saga start event, and related start events, and produce related transaction termination or failure events based on the success or failure of the transaction execution.

Omega will link with Alpha and notify Alpha of these events. Alpha can perform analysis in the background and issue relevant instructions to Omega to perform related rollback recovery based on the execution of Saga transactions.

The advantage of this design is that the Saga implementation code is separated from the user's code. The user only needs to add a few annotations, and the Saga implementation can perform the execution of the Saga event and perform related processing.

Author: rickiyang

Original link: https://www.cnblogs.com/rickiyang/p/13704868.html

If you think this article is helpful to you, you can like it and follow it to support it, or you can follow my public account, there are more technical dry goods articles and related information sharing, everyone can learn and progress together!

 

Guess you like

Origin blog.csdn.net/weixin_50205273/article/details/108709945