The author | Chen Jianbin (funkye) making id: | a364176773 sourcesAlibaba cloud original public account

Seata is an open source distributed transaction solution, star up to 18100+, highly active community, is committed to providing high-performance and easy-to-use distributed transaction services under the microservices architecture, this article will analyze the implementation principle of Seata, let users have a deeper understanding of AT mode.

What is the Seata transaction mode?

1. Seata’s definition of transactions

Seata defines the framework for global transactions.

A global transaction is defined as the overall coordination of several branch transactions:

  1. TM initiates (Begin), commits (Commit), and rolls back (Rollback) global transactions to TC requests.
  2. TM binds the XID representing the global transaction to the branch transaction.
  3. RM registers with the TC to associate the branch transaction with the global transaction represented by the XID.
  4. RM reports the branch transaction execution result to the TC. (optional)
  5. The TC sends the Branch Commit or Branch Rollback commands to RM.

Seata’s global transaction process is divided into two phases:

Execution phase > : Executes branch transactions and ensures that the execution results are Durable and Rollbackable. Completion stage > : According to the decision generated in the execution stage, apply the global Commit or Rollback request sent by TM to TC. > TC command RM drives the branch transaction to Commit or Rollback.

The so-called transaction mode of Seata refers to the behavior mode of branch transactions running under the GLOBAL transaction framework of Seata. > > To be exact, it should be called branch transaction mode.

Different transaction modes differ in that branch transactions use different ways to achieve the goals of the two phases of the global transaction. That is, answer the following two questions:

Execution Phase > : How to implement the service and ensure that the service results are Durable and Rollbackable. Completion stage > : Rollback/commit the transaction after receiving TC’s command.

2. How do other two-phase transactions operate under the Seata transaction framework

1) TCC transaction mode

Let’s start by looking at how TCC transactions fit into the Seata transaction framework:

It can be found that, in fact, it looks very similar to the transaction framework diagram of Seata, and the difference is that RM is responsible for the management, which is the try execution of phase 1 and confirm/ Cancel of phase 2. It is also the Begin(initiated by TM) of the transaction. After BEING called by TM, RM executes the Try method of phase 1. When the calling link is complete, TM informs TC of the phase 2 decision. At this time, TC drives RM to execute phase 2 (send notification, and RM performs confirm/ Cancel).

2) XA transaction mode

As shown in the figure, XA mode is essentially the XA interface that Seata underlayer uses to automatically process in phase one and phase two. For example, in phase 2, the RM of XA creates XAConnection through the proxy user data source, starts XA transaction (XA start) and performs XA-prepare (any XA operation will be persisted and can be recovered even if it goes down). In phase 2, The TC notified RM to perform Commit and Rollback operations on the XA branch.

What is the AT mode?

Let’s start with an example.

1. A phase

SQL: Update product set name = ‘GTS’ WHERE name = ‘TXC’

The execution process of the first stage is insensitive to the user. The business SQL on the user side remains unchanged, but what exactly happens in the next stage of AT mode? Next, a quick word.

  • Select id, name, since from product where name = ‘TXC’.
  • Execute business SQL.
  • Select id, name, since from product where ID = 1.

2. The second stage

Commit: Simply delete the transaction related information (in theory, it is ok not to delete it).

Rollback: The mirror is rolled back.

From the simple example above, it can be found that the AT mode is the automatic compensation transaction. What exactly does the AT do? This will be described below.

How does AT guarantee distributed transaction consistency?

Let’s start with this graph:

Many of you may be wondering AT first, but this is actually a diagram of how non-invasive AT works. First, the user enters from the interface and arrives at the transaction initiator. At this point, for the business developer, the initiator entry is just a business interface. The same business SQL is executed and the same return information is returned to the client. In the background, the user’s SQL is hosted by the Seata agent. The SEATA-AT mode senses all the user’s SQL and acts on it to ensure consistency.

How is Seata-AT invasive-free?

As shown in the figure, when the application starts, Seata will automatically delegate the user’s DataSource. Users who are familiar with JDBC operations are actually familiar with the DataSource. If they get the DataSource, they will know the connection to the DataSource, so they can do some “actions” behind the DataSource. At this point, there is no perception and no intrusion on the user.

When a service request comes in, Seata will parse the user’s SQL, extract the table metadata, and generate the pre-mirror. After executing the service SQL, Seata will save the post-mirror after executing the SQL (we will talk about post-mirror later). Row locks are generated and carried to seata-Server, the TC side, when branches are registered.

At this point, one stage of operation on the Client side is complete, no perception, no intrusion. Now if you think about it, you’ll see that there’s actually a row lock here, and what does that row lock do? This is to follow up on how SEATA-AT ensures transaction isolation under distributed conditions, taking the example from the official website directly.

1. Write the isolation

  • Make sure you get the global lock before committing a phase 1 local transaction.
  • Unable to commit local transaction because global lock could not be obtained.
  • Attempts to acquire the global lock are limited to a certain range, beyond which the local transaction is abandoned and rolled back to release the local lock.

To illustrate:

Tx1, tx2, tx1, tx2, tx1, tx2;

Tx1 start, open local transaction, get local lock, update operation m = 1000-100 = 900. Before a local transaction is committed, the global lock of the record is obtained. The local commit releases the local lock. Tx2 start, open local transaction, get local lock, update operation m = 900-100 = 800. Before the local transaction is committed, the global lock of the record is held by TX1. Tx2 needs to retry to wait for ** global lock **.

Tx1 two-phase global commit, release global lock. Tx2 takes the global lock and commits the local transaction.

If tx1 has a two-phase global rollback, then TX1 needs to re-acquire the local lock of the data and perform the reverse compensation update operation to achieve the rollback of the branch.

If TX2 is still waiting for the global lock for the data and holds the local lock, the branch rollback of TX1 will fail. The branch rollback will continue to retry until tx2’s global lock times out, the global lock is abandoned and the local transaction is rolled back to release the local lock, and the branch rollback of TX1 finally succeeds.

Because the global lock is held by TX1 until tx1 ends, dirty writes do not occur.

At this point, you probably understand the isolation, and I’m sure you’ve understood most of the operations in this stage, so let’s move on to the next stage.

2. Two-stage processing in AT mode

As can be seen from the figure above, during the two-phase commit, TC only sends a notice: delete undoLog recorded in the previous phase, delete related transaction information such as row lock, and then let the transaction blocked due to competing locks proceed smoothly.

The second phase is a rollback, which requires a little more processing.

The first stage of the rollback is when the Client receives the TC notification. It will check the undolog of the corresponding transaction and mirror it to compare the current data (because SeataAT protects distributed transactions from the business application level, if the information in the database is directly modified at the database level at this time, SeataAT can’t row locking isolation effect at this time), if the outside a global transaction data modification, judged to be dirty at this time to write, and write about how Seata because can’t perceive the dirty, at this time can only print log and trigger the exception notice, inform the user need human intervention (specification modify data entry can avoid dirty).

If there is no dirty writing, it is easier to pull out the front mirror, as we all know that transactions need to be atomic, either at the same time, or not at all, in this case, the front mirror records the data before the occurrence, after rolling back, it achieves atomic effects similar to the local transaction. After the rollback, transaction related information, such as undolog, row locks are deleted. The two-stage rollback is over.

Now that I have introduced the principles and ideas of phase I and Phase II of the AT pattern, what does AT look like under Seata’s distributed transaction framework?

As you can see, AT and other transaction patterns have an extra undolog table in the Seata transaction framework (relative to the intrusion point of other patterns), but otherwise, it is almost non-invasive to the business, which is why the AT pattern is so popular in Seata.

3. Differences between AT mode and other two-phase modes supported by Seata

The first thing to understand is that, as of now, there is no single distributed transaction that will fit all scenarios.

Whether AT mode, TCC mode or Saga mode, these modes are proposed, in essence, from the XA specification of certain scenarios can not meet the requirements.

There are three points for comparison:

  • Data lock

In AT mode, the global lock is used to ensure basic write isolation. In fact, data is locked, but the lock is centrally managed on TCS, enabling efficient unlocking without blocking.

In TCC mode, there is no lock. By using the local transaction exclusive lock feature, resources can be reserved for performing operations after a global transaction is decided.

In XA mode, data is locked and reads and writes are constrained by isolation levels until the end of the transaction.

  • Deadlock (protocol blocking)

After the XA mode is prepared, the branch transaction enters the blocking phase. The branch transaction must be blocked before receiving the XA COMMIT or XA rollback.

AT can support degradation, because the lock is stored on the TC side. If Seata has bugs or other problems, it can be directly degraded without any impact on the subsequent business call chain.

TCC does not have this problem.

  • performance

The performance loss mainly comes from two aspects: on the one hand, transaction correlation processing and coordination process, increasing the RT of a single transaction; On the other hand, lock conflicts for concurrent transaction data reduce throughput. In fact, the main reason is the above protocol blocking and data locking.

XA mode its first phase does not commit, in large concurrent scenarios because locks are stored on multiple resource parties (databases, etc.), exacerbating performance degradation.

In AT mode, the lock granularity is down to row level (primary key is required), and all transaction locks are stored on TCS, enabling efficient and rapid unlocking.

TCC mode has the best performance, requiring little RPC overhead and two local transactions. However, it needs to meet the resource reservation scenario and is highly intrusive to services (business developers need to divide each interface into three, one try, and two confirm and cancel for phase 2). For those of you who are not familiar with XA and AT lock&protocol blocking, take a look AT the following figure:

You can try to guess which one is XA? In fact, XA is shown in the following figure. Because XA brings larger lock granularity and longer lock time, the concurrency performance is much worse than AT transaction model, so the popularity of XA mode is not very high up to now.

Seata’s recent plans

  • The console

First, the console is a problem that Seata users have been exposed to for a long time. The lack of a visual interface makes users doubt the reliability of Seata. Moreover, the lack of a console limits the possibility of manual intervention in distributed transactions on Seata. Therefore, the console will be added in the future version 1.5.0, and more students are welcome to join us!

  • Raft integration

The reason for Raft integration, which most users may not know, is that currently the transaction information on the TC side is stored in external storage such as database, Redis, mongodb(PR phase), which makes the Seata-Server cluster completely unavailable if the external storage fails. Even if the Server is clustered, with 10 or more nodes, it will become unavailable, which is unacceptable.

Raft was introduced to make the transaction information of each SEatA-Server consistent. Even if a node went down, the accuracy of the transaction information would not be damaged, so that the consistency of distributed transactions was better guaranteed. (The implementation of Seata-Server Raft will be shared in a new chapter later.)

  • UndoLog compression

This is a relatively large performance optimization in 1.5.0 AT mode. Since the data in the first stage is large and large, and Seata inserts undolog information for the user behind, it may also become large, which may cause slow storage, so Undolog should be compressed. Makes undolog inserts no longer an AT transaction and a big heart attack overhead when the branch data volume is large.

The following is the Seata communication group welcome to join:

  • Nail group: search group number 32033786 into the group

  • QQ group: search 216012363 into the group

conclusion

AT is essentially an agent that performs operations on resources, records the original and changed state, and locks the data to ensure isolation. When an exception occurs in the call chain, all branch data is restored to achieve “atomicity” under distributed transactions.

In the future? redis,mongodb,mq? Look forward to it.

The core value of the Seata project is to build a standardized platform that comprehensively addresses distributed transaction issues.

Based on Seata, the upper application architecture can flexibly choose the appropriate distributed transaction solution according to the requirements of the actual scene. We welcome everyone to participate in the construction of the project and jointly create a standardized distributed transaction platform.