Preface
from CPU To the memory 、 To disk 、 To the operating system 、 To the network , There are unreliable factors in computer system . Engineers and scientists try to use a variety of hardware and software methods to combat this unreliable factor , Ensure that data and instructions are processed correctly . In the field of network, there are TCP Reliable transport protocol 、 In the field of storage, there are Raid5 and Raid6 Algorithm 、 In the field of database, there is a basis for ARIES The transaction mechanism of algorithm theory ……
This article first introduces the transaction of stand-alone database ACID characteristic , Then it points out the difficulties of operating multiple data sources in distributed scenarios , This paper introduces the common distributed transaction solution in distributed system , These solutions ensure that business code operates on multiple data sources , Be able to operate like a single data source , Have ACID characteristic . At the end of this paper, the mature distributed transaction framework is given ——Seata Of AT Implementation of pattern global transaction .
One 、 Single data source transactions & Multi data source transaction
If an application only connects and queries through the connection driver and data source interface in a business flow ( The query here is generalized , Including adding, deleting, checking and modifying ) A specific database , The application can take advantage of the transaction mechanism provided by the database ( If the database supports transactions ) Ensure the reliability of the operation of the records in the library , Reliability here has four semantics :
- Atomicity ,A
- Uniformity ,C
- Isolation, ,I
- persistence ,D
The author will not explain the four meanings here , Learn about single source transactions and their ACID Characteristics are the premise for readers to read this article . It is a complex and delicate process for a single database to realize its own transaction characteristics , for example MySQL Of InnoDB The engine goes through Undo Log + Redo Log + ARIES Algorithm to achieve . This is a big topic , Beyond the scope of this article , If you are interested, you can study it yourself .
A single data source transaction can also be called a stand-alone transaction , Or local affairs .
In a distributed scenario , A system consists of multiple subsystems , Each subsystem has its own data source . Multiple subsystems are used to compose more complex business through mutual adjustment . In the current popular microservice system architecture , Each subsystem is called a microservice , Again, each microservice maintains its own database , To remain independent .
for example , An e-commerce system may be provided by shopping micro service 、 Inventory microservices 、 Orders, microservices, etc . Shopping microservices integrate shopping business by calling inventory microservices and order microservices . When the user requests the shopping micro service provider to complete the order , On the one hand, shopping microservices call inventory microservices to deduct the inventory quantity of corresponding goods , On the other hand, call the order microservice to insert the order record ( For the convenience of describing distributed transaction solutions later , Here is the simplest e-commerce system microservice division and the simplest shopping business process , Subsequent payments 、 Logistics and other businesses are not under consideration ). The e-commerce system model is shown in the figure below :
In the business scenario of user shopping ,shopping-service Our business involves two databases : Inventory (repo_db) And the order Library (repo_db), That is to say g Shopping business is a combination of multiple data sources . As a consumer oriented system , E-commerce system should ensure the high reliability of shopping business , The reliability here is also ACID Four meanings .
However, the local transaction mechanism of a database only deals with the query operations on itself ( The query here is generalized , Including addition, deletion, modification and search ) Work , Cannot interfere with queries on other databases . therefore , The local transaction mechanism provided by the database itself can not ensure the reliability of global operation of multiple data sources .
Based on this , The distributed transaction mechanism for multi data source operation appears .
Distributed transactions can also be called global transactions .
Two 、 Common distributed transaction solutions
2.1 Distributed transaction model
Describe distributed transactions , The following nouns are often used :
- Transaction participants : For example, each database is a transaction participant
- A business coordinator : Services that access multiple data sources , for example shopping-service It's the business coordinator
- Explorer (Resource Manager, RM): Often synonymous with transaction participants
- Transaction manager (Transaction Manager, TM): Usually synonymous with transaction coordinator
In the distributed transaction model , One TM Manage multiple RM, That is, a service program accesses multiple data sources ;TM Is a global transaction manager , Coordinate the progress of multiple local transactions , Make it commit or roll back together , Finally, a global ACID characteristic .
2.2 Second, the general problem and idempotency
The second general problem is a classic problem in the field of network , Used to express the subtlety and complexity of internet protocol design in computer networks . A simplified version of the two generals problem is given here :
A White army was besieged in a valley , On the left and right sides of the valley are the Blues . There are more white troops trapped in the valley than any blue army on either side of the valley , And less than the sum of the two Blues . If a blue army attacks the White army alone , You will surely lose ; But if two Blues attack at the same time , You can win . The commander in chief of the two blues is on the left side of the valley , He wants the two blues to attack at the same time , This will send the order to the blue army on the right side of the valley , To tell you when to launch the attack . Suppose they could only send soldiers across the valley where the White army was ( The only communication channel ) To deliver the message , So when you cross the valley , Soldiers could be captured .
It's only when the messenger gets back and forth , The commander-in-chief can confirm the victory of this war ( Above figure ). Now comes the question , The soldiers sent out to send the letter did not come back , Can the commander-in-chief of the left-wing Blues decide to launch the attack at the time agreed in the order ?
The answer is not sure , The soldiers sent out to send the letter did not come back , He could be in two situations :
1) He was captured before the order was delivered ( Middle picture ), At this time, the right-wing Blues don't know when to attack ;
2) The order is served , But I was captured on the way back ( Below ), At this point the right side know when to attack , But the left side doesn't know if the right side knows when to attack .
Similar problems are common in computer networks , For example, the sender sends a message to the receiver HTTP request , perhaps MySQL Client to MySQL The server sends an insert statement , Then it timed out and didn't get a response . Does the server write successfully or failed ? The answer is not sure , There are several situations :
1) Maybe the request was not sent to the server at all due to a network failure , So the write failed ;
2) Maybe the server received , It's also written successfully , But before sending the response to the client, the server went down ;
3) Maybe the server received , It's also written successfully , Also sent a response to the client , But it didn't reach the client due to network failure .
Whatever the scene , It seems to the client that it is the same result : Its request was not responded to . To ensure that the server writes data successfully , The client can only resend the request , Until you receive a response from the server .
A similar problem is called the network two generals problem .
The existence of the network two generals problem makes the sender of the message often send the message repeatedly , It is not considered successful until the recipient's confirmation is received , But this often leads to repeated sending of messages . For example, when the order module in the e-commerce system calls the payment module to deduct money , If the network failure leads to the second general's problem , The deduction request is sent repeatedly , The result of repeated deduction is obviously unacceptable . So make sure that the debit request in a transaction is sent no matter how many times , The receiver has and only performs one deduction , This guarantee mechanism is called idempotency of the receiver .
2.3 Two-phase commit (2PC) & Three stage commit (3PC) programme
2PC It is a simple model to implement distributed transaction , These two stages are :
1) Preparation stage : The transaction coordinator initiates a query request to each transaction participant :“ I'm going to perform the global transaction , The resources involved in this transaction are distributed among your data sources , Namely ……, You have your own resources ( In other words, they execute local transactions to the stage to be committed )”. Each participant coordinator replies yes( I'm ready , Allow global transactions to be committed ) or no( Indicates that the participant is unable to obtain the local resources required by the global transaction , Because it's locked by other local transactions ) Or timeout .
2) Submission phase : If all the participants responded with yes, The coordinator initiates a transaction commit operation to all participants , Then all participants receive the local transaction commit operation and send it to the coordinator ACK; If any of the participants reply no Or a timeout , The coordinator initiates a transaction rollback operation to all participants , Then, after receiving, all participants perform the local transaction rollback operation and send it to the coordinator ACK.
2PC The process is shown in the figure below :
As can be seen from the above figure , To achieve 2PC, All participants implement three interfaces :
- Prepare():TM Call this interface to ask if each local transaction is ready
- Commit():TM Calling this interface requires each local transaction to commit
- Rollback():TM Calling this interface requires each local transaction to be rolled back
These three interfaces can be simply ( But not exactly ) Comprehend XA agreement .XA Agreement is X/Open The proposed distributed transaction processing standard .MySQL、Oracle、DB2 These mainstream databases all implement XA agreement , So it can be used to implement 2PC Transaction model .
2PC Easy to understand , But there are the following problems :
1) Poor performance , In the preparation stage , Wait for all the participants to return , To enter stage two , in the meantime , The relevant resources on each participant are locked in exclusive ways , Local transactions that participants intend to use these resources can only wait for . Because of this synchronous blocking problem , So it affects the local transaction concurrency of each participant ;
2) When the preparation phase is complete , If the coordinator goes down , None of the participants received a commit or rollback instruction , Lead to all participants “ At a loss ”;
3) In the submission phase , The coordinator sent a submit instruction to all participants , If a participant does not return ACK, So the coordinator doesn't know what's going on inside this participant ( Due to the existence of the network two generals problem , The participant may not have received the commit command at all , Has been in the state of waiting to receive the commit instruction ; It may also have received , And successfully executed the local commit , But returned ACK The network failure did not reach the coordinator ), It is impossible to decide whether to roll back all participants in the next step .
2PC And then again 3PC, Turning a two-stage process into a three-stage process , Namely : Inquiry stage 、 Preparation stage 、 Commit or rollback phase , No more details here .3PC Using the timeout mechanism to solve 2PC The problem of synchronization blocking , Avoid permanent locking of resources , Further enhance the reliability of the whole transaction process . however 3PC It's also impossible to deal with similar downtime issues , However, the probability of data inconsistency in multiple data sources is smaller .
2PC Except for performance and reliability problems , It's also very limited in its application scenarios , It requires participants to implement XA agreement , For example, we have realized XA The protocol's database as a participant can complete 2PC The process . But in multiple systems, services take advantage of api When interfaces call each other , They don't abide by XA It's agreed , Now 2PC It doesn't apply . therefore 2PC Rarely used in distributed application scenarios .
Therefore, the e-commerce scenario mentioned above cannot be used 2PC, because shopping-service adopt RPC Interface or Rest Interface call repo-service and order-service Indirect access to repo_db and order_db. Unless shopping-service Direct configuration repo_db and order_db As your own database .
2.4 TCC programme
describe TCC The e-commerce micro service model used in the scheme is shown in the figure below , In this model ,shopping-service It's the business coordinator ,repo-service and order-service It's a transaction participant .
Mentioned above ,2PC Participants are required to implement XA agreement , It is usually used to solve the transaction problem between multiple databases , More limited . Service utilization in multiple systems api When interfaces call each other , They don't abide by XA It's agreed , Now 2PC It doesn't apply . Modern enterprises adopt distributed microservices , Therefore, it is more important to solve the problem of distributed transactions among multiple microservices .
TCC It is a solution to the problem of distributed transactions among multiple microservices .TCC yes Try、Confirm、Cancel An abbreviation for three words , Its essence is an application level 2PC, There are also two stages :
1) Stage 1 : Preparation stage . The coordinator invokes all of the try Interface , Lock the resources involved in the whole global transaction , If the lock is successful try Interface returns to the coordinator yes.
2) Stage two : Submission phase . If all the services try The interface returns in phase one yes, Then it enters the commit phase , The coordinator invokes the confirm Interface , Each service commits the transaction . If there is any service try The interface returns in phase one no Or a timeout , Then the coordinator calls the cancel Interface .
TCC The process is shown in the figure below :
Here's a key question , since TCC It's a service level 2PC, How does it solve 2PC Can't deal with the downtime problem defects ? The answer is to try again and again . because try The operation locks all the resources involved in the global transaction , It ensures that all preconditions of business operation are satisfied , So whether or not confirm Stage failure or cancel Phase failure can be achieved by repeatedly retrying until confirm or cancel success ( Success is that all services are right confirm perhaps cancel Back to ACK).
Here's another key question , Trying again and again confirm and cancel In the process of ( Considering the existence of general problem of network two ) It may have been repeated confirm or cancel, So we have to make sure that confirm and cancel Operations are idempotent , That is, in the whole global transaction , Each participant did it only once confirm perhaps cancel. Realization confirm and cancel Idempotence of operation , There are many solutions , For example, each participant can maintain a de duplication table ( It can be implemented by using database table or memory type KV Component implementation ), Record every global transaction ( Mark with global transaction XID distinguish ) Have you ever done confirm or cancel operation , If it has been done , It is no longer repeated .
TCC Put forward by the Alipay team , Is widely used in the financial system . When we buy funds with bank account balances , It will be noted that the balance in the bank account used to purchase the fund will be frozen in the first place , From this we can guess , This process is probably TCC The first stage of .
2.5 Transaction state table scheme
There's another one that's similar to TCC Transaction solutions for , With the help of transaction state table . Suppose you want to implement a call in a distributed transaction repo-service Deducting the inventory 、 call order-service There are two processes to generate an order . In this scheme , The coordinator shopping-service Maintain a transaction status table as follows :
The initial state is 1, The status is updated every time a service is successfully called , Finally, all service calls succeed , Status update to 3.
With this watch , You can start a background task , Scan the status of transactions in this table , If a distributed transaction always ( Set a transaction cycle threshold ) Not in state 3, This indicates that the transaction was not successfully executed , So you can call again repo-service Deducting the inventory 、 call order-service Generate order . Until all calls succeed , Transaction status to 3.
If multiple retries still remain in the State 3, You can set the transaction state to error, Intervene by artificial intervention .
Due to the existence of service call retries , Therefore, the interface of each service should be based on the global distributed transaction ID Do idempotent , The principle is the same as 2.4 The realization of idempotency of a section .
2.7 The final consistent transaction scheme based on message middleware
Whether it's 2PC & 3PC still TCC、 Transaction status table , Basically abide by XA The idea of agreement , In other words, these schemes are essentially transaction coordinators to coordinate the progress of local transactions of each transaction participant , Make all local transactions commit or roll back together , Finally, a global ACID characteristic . In the process of coordination , The coordinator needs to collect the current state of each local transaction , According to these States, the next stage operation instructions are issued .
However, these global transaction schemes are cumbersome to operate 、 The time span is large , Or lock the related resources exclusively during the global transaction , The concurrency of global transactions in the whole distributed system will not be too high . This is difficult to meet the transaction throughput requirements of e-commerce and other high concurrency scenarios , So Internet service providers have explored a lot with XA Distributed transaction solutions that run counter to protocols . The final consistent global transaction implemented by message middleware is a classic scheme .
To show the essence of this scheme , I will use the following e-commerce system microservice architecture to describe it :
In this model , Users are no longer requested to integrate shopping-service Place an order , It's a direct request order-service Place an order ,order-service On the one hand, add order records , On the other hand, it calls repo-service Deducting the inventory .
This kind of final consistent transaction scheme based on message oriented middleware is often misunderstood as the following implementation mode :
The process of this implementation is :
1)order-service Responsible for providing MQ server Send stock deduction message (repo_deduction_msg);repo-service subscribe MQ server Reduced inventory message in , Responsible for consumer information .
2) After the user orders ,order-service First execute the query statement to insert the order record , After the repo_deduction_msg Send to message middleware , These two processes are carried out in a local transaction , once “ Execute the query statement that inserts the order record ” Failure , Cause transaction rollback ,“ take repo_deduction_msg Send to message middleware ” It won't happen ; Again , once “ take repo_deduction_msg Send to message middleware ” Failure , Throw an exception , It can also lead to “ Execute the query statement that inserts the order record ” Operation rollback , In the end, nothing happened .
3)repo-service Received repo_deduction_msg after , Execute inventory deduction query statement first , Back MQ sever Feedback message consumption completed ACK, These two processes are carried out in a local transaction , once “ Execute inventory deduction query statement ” Failure , Cause transaction rollback ,“ towards MQ sever Feedback message consumption completed ACK” It won't happen ,MQ server stay Confirm Driven by the mechanism, it will continue to repo-service Push the message , Until the entire transaction is successfully committed ; Again , once “ towards MQ sever Feedback message consumption completed ACK” Failure , Throw an exception , It also leads to “ Execute inventory deduction query statement ” Operation rollback ,MQ server stay Confirm Driven by the mechanism, it will continue to repo-service Push the message , Until the entire transaction is successfully committed .
This seems to be a reliable approach . But did not take into account the existence of the network two generals problem , It has the following defects :
1) There is a network of 2 General question , The above first 2) In step order-service send out repo_deduction_msg The news failed , For the sender order-service Come on , Maybe the message middleware didn't receive the message ; It may also be that the middleware has received the message , But to the sender order-service Responsive ACK Due to network failure, it was not order-service received . therefore order-service Hasty transaction rollback , revoke “ Execute the query statement that inserts the order record ”, It is not right , because repo-service It may have been received over there repo_deduction_msg And the inventory deduction is successful , such order-service and repo-service There is a data inconsistency between the two sides .
2)repo-service and order-service Call the network ( And MQ server signal communication ) Put it in a local database transaction , Long database transactions may occur due to network latency , Affect the concurrency of local transactions in the database .
The above is a misunderstood way to achieve , Here's how to do it , As shown below :
The scheme shown above , Using message middleware such as rabbitMQ To achieve the final consistency of distributed order and inventory deduction process . Let's illustrate the picture below :
1)order-service in ,
stay t_order Table add order record &&
stay t_local_msg Add the corresponding deduction stock message
These two processes need to be completed in one transaction , Guarantee the atomicity of the process . Again ,repo-service in ,
Check whether the inventory deduction operation has been performed &&
Perform inventory deduction if this deduction has not been performed &&
Write a duplicate list &&
towards MQ sever Feedback message consumption completed ACK
These four processes should also be completed in one transaction , Guarantee the atomicity of the process .
2)order-service There's a background program in , The message in the message table is continuously transmitted to the message middleware , After success, delete the corresponding message in the message table . If it fails , And try to retransmit . Because of the network 2 General question , When order-service Message network timeout sent to message middleware , At this time, the message middleware may receive the message but respond ACK Failure , Maybe I didn't get it ,order-service The message will be sent again , Until the message middleware responds ACK success , This may cause repeated messages to be sent , But that's okay , As long as the message is not lost , Just keep in order , Back repo-service Will do reprocessing .
3) Message oriented middleware to repo-service push repo_deduction_msg,repo-service After successful processing, it will respond to the middleware ACK, Message middleware receives this ACK Just think repo-service Successfully processed the message , Otherwise, the message will be pushed repeatedly . But there are situations like this :repo-service Successfully processed the message , Sent to middleware ACK Lost in network transmission due to network failure , As a result, middleware did not receive ACK Re pushed the message . It also depends on repo-service To avoid repeated message consumption .
4) stay 2) and 3) There are two causes of repo-service The reason for receiving the message repeatedly , First, producers produce repeatedly , Second, middleware retransmission . In order to realize the idempotency of business ,repo-service A duplicate table is maintained in , This table records the message that has been successfully processed id.repo-service Every time a new message is received, it is judged whether the message has been successfully processed , If so, don't repeat it .
Through this design , The message is not lost in the sender , Messages are not consumed repeatedly by the receiver , Together, the news is not missing or heavy , Strictly achieved order-service and repo-service The final consistency of the data in the two databases of .
The final consistent global transaction scheme based on message middleware is an innovative application mode explored by Internet companies in high concurrency scenarios , utilize MQ Realize asynchronous call between microservices 、 Decoupling and peak shaving , Support high concurrency of global transactions , And ensure the final consistency of distributed data records .
3、 ... and 、Seata in AT mode The implementation of the
The first 2 In this chapter, we give the common theory model of realizing distributed transaction . This chapter presents the industry open source distributed transaction framework Seata The implementation of the .
Seata It provides users with AT、TCC、SAGA and XA Transaction mode . among AT The pattern is Seata The main transaction mode , Therefore, this chapter analyzes Seata in AT mode The implementation of the . Use AT There is a premise , That is, the database used by microservices must be a transactional relational database .
3.1 Seata in AT mode Workflow Overview
Seata Of AT The schema is based on the local transaction characteristics of relational databases , Through the data source proxy class intercepts and parses the database execution SQL, Log custom rollback logs , To roll back , Replay these custom rollback logs .AT The pattern is based on XA Transaction model (2PC) Evolved from , however AT To break the XA The blocking constraints of the protocol , Balance between consistency and performance .
AT The pattern is based on XA The transaction model evolved from , Its overall mechanism is also an improved version of the two-phase commit protocol .AT The two basic stages of the model are :
1) The first stage : First get the local lock , Performing local transactions , Business data operations and logging rollback logs are committed in the same local transaction , Finally release the local lock ;
2) The second stage : To submit globally , Delete the rollback log asynchronously , This process will soon be completed . If you need to roll back , The first phase of the rollback log is used for reverse compensation .
This chapter describes Seata in AT mode The working principle of e-commerce micro service model is shown in the figure below :
In the diagram above , The coordinator shopping-service Call participants first repo-service Deducting the inventory , Then the participant is called order-service Generate order . This stream uses Seata in XA mode The global transaction flow after that is shown in the following figure :
The global transaction execution process described in the above figure is :
1)shopping-service towards Seata Register global transactions , And generate a global transaction identifier XID
2) take repo-service.repo_db、order-service.order_db The local transaction for is executed to the pending commit phase , The content of the transaction contains the right to repo-service.repo_db、order-service.order_db Query operations and write to each library undo_log Record
3)repo-service.repo_db、order-service.order_db towards Seata Register branch transactions , And include it in the XID Corresponding global transaction scope
4) Submit repo-service.repo_db、order-service.order_db The local affairs of
5)repo-service.repo_db、order-service.order_db towards Seata Reports the commit status of branch transactions
6)Seata Sum up all the DB The commit status of the branch transaction of , Decide whether the global transaction should be committed or rolled back
7)Seata notice repo-service.repo_db、order-service.order_db Submit / Rollback local transaction , If you need to roll back , It's a compensatory approach
among 1)2)3)4)5) It belongs to the first stage ,6)7) It belongs to the second stage .
3.1Seata in AT mode Workflow details
In the above e-commerce business scenario , Shopping service calls inventory service to deduct inventory , Call the order service to create an order , Obviously, these two calling procedures should be placed in one transaction . namely :
start global_trx
call Inventory service deduction inventory interface
call Order service creation order interface
commit global_trx
In the inventory service database , There are the following inventory tables t_repo:
In the order service database , There are the following order forms t_order:
Now? ,id by 40002 The user wants to buy a commodity code for 20002 The mouse , The content of the whole distributed transaction is :
1) The inventory table of the inventory service will record
It is amended as follows
2) Add a record to the order table of the order service
The above operation , stay AT The flow chart of the first phase of the pattern is as follows :
from AT The process of the first stage of the model is , The local transaction of the branch is completed after the first phase commit , Local records locked by local transactions will be released . This is a AT Patterns and XA The biggest difference , stay XA Two phase commit of transaction , Locked records are not released until the end of the second phase . therefore AT The mode reduces the lock record time , Thus, the efficiency of distributed transaction processing is improved .AT The reason why the pattern is able to release the locked records after the first phase is completed , Because Seata In the database of each service, one is maintained undo_log surface , It's written about t_order / t_repo Mirror data recorded before and after operation , Even if the second phase is abnormal , Just play back the undo_log Global rollback can be realized by corresponding records in .
undo_log The table structure :
After the first phase ,Seata The commit status of all branch transactions will be received , Then decide whether to commit the global transaction or roll back the global transaction .
1) If all branch transactions are successfully committed locally , be Seata Decide to commit globally .Seata Send the message submitted by the branch to each branch transaction , After each branch transaction receives the branch commit message , The message is put into a buffered queue , Then go straight to Seata Return submitted successfully . after , Each local transaction will slowly process the branch commit message , The way to deal with it is : Delete... Of the corresponding branch transaction undo_log Record . The reason is that you only need to delete the branch transaction undo_log Record , There is no need to do other commit operations , Because the commit operation has been completed in the first phase ( This is also AT and XA Different places ). This process is shown in the figure below :
The reason why branch transactions can directly return success to Seata, Because the really critical commit operation has been completed in the first phase , eliminate undo_log The journal is just a finishing line , Even if the purge fails , It also has no substantial impact on the whole distributed transaction .
2) If any branch transaction local commit fails , be Seata Decide to roll back globally , Send the branch transaction rollback message to each branch transaction , Since the database of each service in the first phase recorded undo_log Record , The branch transaction rollback operation only needs to be based on undo_log Record and compensate . The global transaction rollback process is shown in the following figure :
Here's the picture of 2、3 Step for further explanation :
1) As given above undo_log The table structure , So you can go through xid and branch_id To find all the undo_log Record ;
2) Get the current branch transaction undo_log After recording , The first thing to do is to verify the data , If afterImage The record in is inconsistent with the current table record , Explain the period from the completion of the first stage to the present moment , There are other transactions that have modified these records , This causes the branch transaction not to be rolled back , towards Seata Feedback rollback failed ; If afterImage The record in is consistent with the current table record , Explain the period from the completion of the first stage to the present moment , No other transaction modifies these records , Branch transactions can be rolled back , And then according to beforeImage and afterImage Calculate the compensation SQL, Execution compensation SQL Roll back , Then delete the corresponding undo_log, towards Seata Feedback rollback successful .
The transaction is ACID characteristic , Global transaction solutions are also trying to implement these four features . The above is about Seata in AT mode It is obvious that AT The atomicity of 、 Consistency and persistence . Let's focus on AT How to ensure the isolation of multiple global transactions .
stay AT in , When multiple global transactions operate on the same table , To ensure transaction isolation through global lock . The following describes how global locks work in both read isolation and write isolation scenarios :
1) Write isolation ( If there is a global transaction changing / Write / Delete the record , Another global transaction changes the same record / Write / The deletion should be isolated , That is, writing is mutually exclusive ): Write isolation is used when multiple global transactions update the same field in the same table , To avoid the data involved in a global transaction being modified by other global transactions before it is successfully committed . The basic principle of write isolation is : In the first stage, local affairs ( When opening local affairs , Local transactions will lock the records involved locally ) Before submitting , Make sure you get the global lock . If you can't get the global lock , You can't commit local transactions , And keep trying to get global locks , Until the number of retries is exceeded , Give up global lock , Rollback local transaction , Release the local lock imposed by the local transaction on the record .
Suppose there are two global transactions gtrx_1 and gtrx_2 In concurrent operation of inventory service , Intention to deduct the inventory quantity recorded below :
AT The sequence diagram for the write isolation process is as follows :
In the figure ,1、2、3、4 It belongs to the first stage ,5 It belongs to the second stage .
In the diagram above gtrx_1 and gtrx_2 All submitted successfully , If gtrx_1 Perform the rollback operation in the second phase , that gtrx_1 Need to re initiate local transaction to obtain local lock , And then according to undo_log For this id=10002 The records are rolled back competitively . here gtrx_2 Still waiting for global lock , And hold this id=10002 Local lock for records of , therefore gtrx_1 Will fail to roll back (gtrx_1 Rollback requires holding both global locks and pairs of id=10002 Local lock on records of ), Rollback failed gtrx_1 Will always try to roll back . To the next one gtrx_2 The number of attempts to acquire a global lock exceeded the threshold ,gtrx_2 Will give up getting the global lock , Initiate local rollback , After the local rollback ends , It's natural to let go of this id=10002 Local lock on records of . here ,gtrx_1 Finally, we can succeed in this id=10002 A local lock has been added to the record , And I got both local and global locks gtrx_1 You can successfully roll back . The whole process , The global lock is always in gtrx_1 In the hands of , There's no dirty writing problem . The flow chart of the whole process is shown below :
2) Reading isolation ( If there is a global transaction changing / Write / Delete the record , Another global transaction's reading of the same record should be isolated , Reading and writing are mutually exclusive ): At the isolation level of database local transactions, read committed 、 Repeatable 、 When serializing ( Read uncommitted doesn't work as a quarantine , Generally not used ),Seata AT The isolation level generated by the global transaction model is read uncommitted , That is to say, a global transaction will see the data not globally committed by another global transaction , Produce dirty reading , This can also be seen from the flow charts of the first and second stages . This is acceptable in a ultimately consistent distributed transaction model .
If required AT The model must implement read committed transaction isolation level , You can use Seata Of SelectForUpdateExecutor The actuator is right SELECT FOR UPDATE Statement to proxy .SELECT FOR UPDATE Statement will apply for a global lock when it is executed , If the global lock is already held by another global transaction , Then roll back SELECT FOR UPDATE Execution of statements , Release local lock , And try again SELECT FOR UPDATE sentence . In the process , Query requests will be blocked , Until you get the global lock ( In other words, the record to be read is committed by other global transactions ), Read the data that has been committed by the global transaction before returning . This process is shown in the figure below :
Four 、 Conclusion
XA Agreement is X/Open The proposed distributed transaction processing standard . Mentioned in the article 2PC、3PC、TCC、 Local transaction table 、Seata in AT mode, Either way , The essence is that the transaction coordinator coordinates the progress of the local transaction of each transaction participant , To cause all local transactions to commit or roll back together , Finally, a global ACID characteristic . In the process of coordination , The coordinator needs to collect the current state of each local transaction , According to these States, the next stage operation instructions are issued . The idea is XA The essence of the agreement , We can say that these transaction models comply with or generally comply with XA agreement .
The final consistent transaction scheme based on message middleware is an innovative application mode explored by Internet companies in high concurrency scenarios , utilize MQ Realize asynchronous call between microservices 、 Decoupling and peak shaving , Ensure the final consistency of distributed data records . It clearly does not comply XA agreement .
For a technology , There may be industry standards or protocols , However, practitioners need specific application scenarios or for convenience , The implementation of the standard is not completely consistent with the standard , Even completely inconsistent implementations , This is a common phenomenon in engineering .TCC This is the plan 、 The final consistent transaction scheme based on message middleware is as follows 、Seata in AT mode The pattern is the same . And new standards often emerge from these innovations .
Don't you really find out 2.6 section ( The final consistent transaction scheme based on message middleware ) Is there a business vulnerability in the right solution given ? Please take a look at this picture again , Take a careful look at the calling directions of two microservices , Leave your thoughts in the comments section :-)
At the end
Welcome to my official account 【 Calm as a code 】, Massive Java Related articles , Learning materials will be updated in it , The sorted data will also be put in it .
Like what you write , Just pay attention ! Focus , Neverlost , Continuous updating !!!