preface
As we all know, distributed transactions are a complex problem, with many different ideas and approaches.
At present, as long as the micro-service architecture does the distributed system, the topic of distributed transactions can not be avoided. Of course, the use of distributed transaction solutions does not make the service stable and high, and the absence of distributed transaction services is not necessarily bad. At present, our company does not use distributed transactions, but also supports a stable, flexible system. The choice of a distributed transaction is not right or wrong, but a choice made after weighing the pros and cons in a real project.
Distributed transaction development source
Our application started as a single service, and when used properly, Spring’s transactions can help us out with related transactions. A brief analysis of a Spring transaction: after a proxy method uses @TransactionA and is cut by an AOP facet. Spring uses ThreadLocal to manage the same DBConnection for the AOP facets. This Connection manages the transaction for us: that is, when the entire method finishes executing (a live exception), the transaction is committed or rolled back together. At this point, our application is shown as follows:
Or it
However, with the growth of project traffic, the same DB connection certainly cannot accept all kinds of service data. Therefore, in actual projects, the relationship between most of our applications and DB is as follows:
As we know, Spring transactions are controlled under a single JVM via the same DB connection, but when there are multiple servers and different servers have their own JVMs, even if the call is made remotely, the DB-connection is definitely not the same. As a result, we need a third party to coordinate the data connection for each service. This leads to what is often referred to as the distributed transaction problem.
Prepare knowledge points
-
ACID
(4) They want to look good. (5) Atomic Consistency Isolation Durability
-
Isolation level
Read Uncommitted(Read) Repeated Read(Serialization) Repeated Read(Serialization)
-
The laws of CAP
Consistency (C) whether all data backed up in a distributed system are of the same value at the same time. Availability (A) Whether the cluster as A whole can still respond to read and write requests from clients after the failure of some nodes in the cluster. (High Availability for Data Updates) Partition Fault Tolerance (P) In practical terms, partitioning is equivalent to time requirements for communication. If the system does not reach data consistency within the time limit, it means that A partitioning situation has occurred and that it must choose between C and A for the current operation.
- “Base” is an acronym for Basically Available, Soft state, and Eventually consistent. Base theory is the result of tradeoff between consistency and availability in CAP, which is derived from the summary of distributed practice of large-scale Internet systems, and is gradually evolved based on the CAP theorem. The core idea of BASE theory is: even if strong consistency cannot be achieved, each application can adopt appropriate methods to achieve final consistency according to its own business characteristics.
Basic availability refers to the fact that a distributed system is allowed to lose some of its availability in the event of an unpredictable failure -- note that this is by no means equivalent to the system being unavailable. For example: (1) Loss of response time. Under normal circumstances, an online search engine needs to return the corresponding query results to the user within 0.5 seconds, but due to the failure, the response time of the query results is increased by 1~2 seconds. (2) Loss of system functions: Under normal circumstances, when shopping on an e-commerce website, consumers can almost complete every order smoothly. However, in some festivals, in order to protect the stability of the shopping system, due to the surge of consumers' shopping behavior, Some consumers may be directed to the soft soft state refers to a downgrade page allows the system to the data in the intermediate state, and that the presence of the intermediate state does not affect the system's overall availability, which allows the system between the different nodes copy data to data synchronization is the process of time delay Eventual consistency Eventual consistency that copy of all of the data, After a period of synchronization, they will eventually reach a consistent state. Therefore, the essence of the final consistency is that the system needs to ensure that the final data can achieve the consistency, but does not need to guarantee the strong consistency of the system data in real time.
Open source distributed transaction framework
There are a number of frameworks available for open source distributed transaction issues, such as Seata, LCN, RocketMQ using transactional messaging, and so on. There are many different patterns supported under each framework (think about why each framework supports several patterns). Today we’ll take a closer look AT Seata’s non-intrusive AT mode.
Let’s start with a simple SATA example
= = = = = = = = = = = = user module = = = = = = = = = = = = = / * * * @ author liuliang * @ date 2021/7/9 "* / afternoon @ Slf4j @ Service public class UserService extends ServiceImpl<UserMapper, UserInfo> { @Resource private OrderFeign orderFeign; @GlobalTransactional public void buyProduct() { UserInfo userInfo = this.getById(1L); userInfo.setAmount(userInfo.getAmount() - 1); This. updateById(userInfo); this.updateById(userInfo); // Create order orderFeign. Test (); Log.info (" End of purchase "); }}
The User module invokes the Order module
/** * @author liuliang * @date 2021/7/9 2:58 PM */ @FeignClient(name = "Mm-order ") public interface OrderFeign { @GetMapping("/order/test") void test(); }
The order module
/** * @author liuliang * @date 2021/7/9 3:05 PM */ @slf4j @service public class orderService extends ServiceImpl<OrderMapper, OrderInfo> { public void test() { OrderInfo orderInfo = new OrderInfo(); orderInfo.setNum(1); orderInfo.setPrice(100L); OrderInfo.setSkuname (" little video "); this.save(orderInfo); Log.info (" Small video data saved "); // throw new RuntimeException("111"); }}
As you can see, when the User module adds Seata’s @GlobalTransactional annotation, when the Order module fails, the User is rolled back and different agent connections belonging to two different JVMs can be in the same transaction! Now let’s analyze the principle of SEATA
- Seata framework
As you can see, Seata has three components:
2. RM (Resource Manager) Data Source Manager 3. TC (Transaction Coordinator
In general, the flow of a distributed transaction can be analyzed as the following steps:
1. TM applies to TC to start a global transaction. The global transaction is created successfully and a globally unique XID is generated. 2. The XID is propagated in the context of the micro-service invocation link. 3. RM registers branch transactions with TC and brings them into the jurisdiction of XID corresponding global transactions. 4. TM initiates a global commit or rollback resolution against XID to TC. 5. TC dispatches all branch transactions under XID to complete the commit or rollback request.
Before analyzing the execution process of Seata in detail, we will demonstrate the following simple demos: Exception before User calls Order; Exception when User calls Order; Exception when User calls Order; Exception after User calls Order (breaking point at Order). Next, let’s solve the puzzle step by step through the form of questions: 1. What is undo_log and when did it arise? And when to disappear?
io.seata.rm.datasource.undo.mysql.MySQLUndoLogManager#insertUndoLogWithNormal IO. Seata. Tm. API. TransactionalTemplate# execute io.seata.core.rpc.net. Ty RmMessageListener# onMessage after reading the source code, found that seata agent in the data source layer, Before the local transaction commits, insert the pre - and post-modification records into the UNDO_LOG table. At the end of the section, if the transaction is normal, then the global commit is triggered. When the global commit occurs, TM notifies TC, and TC detects each branch transaction and deletes UNDO_LOG data. If the transaction is abnormal, then the global rollback is initiated. Then delete undlog
2. Will there be cases where undo_log is inconsistent with local things?
No, in the local transaction, the business logic and undo_log are in the same transaction
3. If a piece of data is modified by another transaction during execution, is the data incorrectly encoded? (Or isolation)
Write/read isolation, interpret global locking, local locking
4. Why does SEATA or LCN have multiple modes to handle distributed transactions?
Capability boundary, Seata will require a native database to support transactions and to have a primary key
To summarize the AT mode of SEATA: Seata’s AT mode is based on the characteristics of local transactions. By intercepting and parsing SQL, it records the custom rollback log, thus breaking the constraints of XA protocol blocking, and achieving a balance in consistency, performance and ease of use: Under the premise of certain consistency (not final consistency), high performance can be guaranteed and no intrusion into the business can be achieved at all. Seata’s AT mode works well in the vast majority of application scenarios, reducing the cost of distributed transaction support to a very low level.