preface

Distributed transaction is divided into two concepts: distributed and transaction. Distributed transaction simply means communication between systems of different processes. In the narrow sense, transactions are often regarded as database transactions. Transactions have ACID properties, namely: Atomicity, Consistency, Isolation, Persistence, colloquially speaking, they all succeed or fail for database updates within the same transaction. Broadly speaking, a batch of operations within the same transaction (not limited to database operations) either all succeed or all fail; In summary, transaction participants are located in different process nodes.

Distributed theory

Since it is related to distribution, it is necessary for us to understand several theories of distributed system CAP and Base theory;

Theory of CAP

It is impossible for a distributed system to meet the three basic needs of Consistency, Availability and Partition tolerance at most, only two of them simultaneously.

Consistency: All nodes have the same data at the same time. For example, operations such as user order generation, inventory reduction, and user payment will either succeed or fail together. Availability: The service is always available with normal response time; Zone fault tolerance: A distributed system can provide consistent and available services even when a node or network partition fails.

For a distributed system, fault tolerance of partition is the most basic requirement. So most of the time it’s really a tradeoff between CA and CA; Distributed transactions also have this choice, such as the X/Open XA protocol, which is described below, which favors consistency; However, in the face of the high concurrency of Internet, such strong consistency causes great performance problems, and flexible transaction based on BASE theory may be a better choice.

The BASE theory of

BASE is short for Basically Available, Soft state, and Eventually consistent. Obviously, BASE theory is more inclined to meet the AP in CAP theory. The system that meets availability and partition tolerance may generally have lower requirements for consistency.

BASE theory and ACID can be said to be completely opposite, ACID guarantees strong consistency at the expense of availability, BASE theory is to replace strong consistency with final consistency to ensure availability; In actual scenarios, different businesses have different data requirements, so BASE theory and ACID are used together in most cases.

Typical flexible transaction schemes based on BASE theory: maximum effort notification, TCC, asynchronous assurance, etc.

The CAP, ACID and BASE theories can be intuitively understood by the following figure:

Distributed transaction scenario

Before introducing the distributed transaction scenario, we first do a simple understanding of local transactions, which is the most commonly used transaction in our daily life. Basically, mainstream databases support local transactions, and basically meet the characteristics of ACID.

Local transactions

A process corresponds to a database. All participants of a transaction are in a process and operate on the same database.

Java.sql.Connection provides operations such as committing and rolling back transactions. The code is roughly as follows:

Connection conn = DriverManager.getConnection(...) // Get the database connection
// In JDBC, the default value is true to commit transactions automatically, false to disable automatic commit
conn.setAutoCommit(false);
try {
	// Database operation 1
	// Database operation 2
	conn.commit(); // Commit the transaction
} catch (Exception e) {
	conn.rollback();// Transaction rollback
} finally {
	conn.close();// Close the link
}
Copy the code

Of course, Java does not provide transaction support, all support is provided by the database, such as mysql related transaction operations:

mysql> begin;
Query OK, 0 rows affected (0.00 sec)

mysql> insert into t_order0 (user_id,order_id) values ('110'.'1212');
Query OK, 1 row affected (0.00 sec)

mysql> insert into t_order0 (user_id,order_id) values ('111'.'1213');
Query OK, 1 row affected (0.00 sec)

mysql> commit;
Query OK, 0 rows affected (0.03 sec)
Copy the code

, of course, if each business transaction is to write it again so it is trouble, completely can do it by AOP cut processing, the Spring can be very good to help us to complete the transaction processing, provides a unified PlatformTransactionManager transaction management interface, the realization of the common categories:

DataSourceTransactionManager: used to manage local affairs;

JtaTransactionManager: support distributed transactions implement the JTA specification, using XA protocol for two-phase commit;

<bean id="dataSourceTransactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
		<property name="dataSource" ref="dataSource" />
</bean>

<tx:advice id="txAdvice" transaction-manager="dataSourceTransactionManager">
	<tx:attributes>.</tx:attributes>
</tx:advice>

<aop:config>.</aop:config>
Copy the code

You can configure which classes and methods need to be transacted through the section, as well as @transitional annotations.

Distributed transaction

With the popularity of SOA architecture and microservices, distributed transactions also appear in many scenarios, including: single application with multiple data sources, multiple applications with single data sources, multiple applications with multiple data sources;

Single application with multiple data sources

In this case, the database may be split for different services, but the application has not been split, or the database is divided into database and table operations for a large amount of data.

Note: The data source is not necessarily a database, but could be a data source such as MQ.

Multiple applications single data source

This situation occurs in many systems using Oracle database. The database is powerful and multiple applications share the same database, which is common in many financial systems.

Multiple applications and multiple data sources

This situation is common in various SOA architectures, microservice systems, and should be said to be the most common scenario at present, where each process is called through RPC;

Distributed transactions are used in all of the above scenarios. Of course, CAP theory is also mentioned above, and the processing method of distributed transactions will be based on your business logic. However, the DTP model is the standard for distributed transaction processing.

DTP model and XA specification

The DTP model and XA specification are industry standards defined by an organization called X/Open;

X/Open International Consortium LTD is a European foundation established to provide standards for UNIX environments. Its primary goal is to facilitate the development of open system protocols for the UNIX language, interfaces, networks, and applications. It also promotes application interoperability between different UNIX environments, as well as supporting the IEEE Portable Operating System Interface (POSIX) specification for UNIX.

You can refer to the following documents for specifications:

Distributed Transaction Processing (DTP) Model: Distributed Transaction Processing: Reference Model

Distributed Transaction Processing (DTP)XA Specification: The XA Specification

The DTP model

The X/Open DTP model consists of five basic functional components:

  • Application Program: Defines transaction boundaries and specifies the operations that make up the transaction;
  • Resource Managers (RMs) : Full name for Resource Managers, such as databases or file access systems, that provide access to resources;
  • Transaction Manager (TM) : Full name Transaction Manager, assigns identifiers to transactions, monitors their progress, and is responsible for Transaction completion and coordinating fault recovery;
  • CRM: Full name Communication Resource Managers, used to control Communication between distributed applications within or across TM domains;
  • Communication Protocol (CP) : Communication Protocol, which provides the underlying Communication services used by distributed applications and supported by CRM.

A model instance

Each instance can support one AP, one TM, and multiple RMs. Distributed applications are represented by two or more instances, each containing a CRM;

This model can be said to be the simplest model, corresponding to the above single application of multiple data sources; For distributed applications that require multiple instances, the model is as follows:

It can be found that each model instance has an additional CRM module, which is mainly used for communication between distributed applications. Can be used to solve the case of multiple applications;

Transaction manager scope

A TM domain consists of one or more instances that use the same TM, which is common to all applications running in that TM domain. Common TM uses logically shared data structures and logs for global transaction management;

When distributed communication occurs between two instances, they have a superior and subordinate relationship. The instance that requests another instance to participate in the global transaction is called the superior, and the instance that requests another instance is called the subordinate instance, especially the instance that has no superior is called the root. In the X/ OPENDTP model, a tree structure is used to manage global transactions across distributed AP operations.

XA specification

The following figure shows a local instance of a DTP system where AP calls TM to construct a transaction. These boxes represent software components in the X/Open DTP model; Arrows indicate the direction of the control flow;

The topic of the X/Open specification is the interface (3) in the figure above, the XA interface for TMs and RMs interaction;

XA interface

The interface between RM and TM is defined as follows:

  1. Ax_reg: register RM with TM;
  2. Ax_unreg: Deregister RM using TM.
  3. Xa_close: terminates AP’s use of RM.
  4. Xa_commit: tells RM to commit the transaction branch;
  5. Xa_complete: Tests whether the asynchronous xa_ operation has completed;
  6. Xa_end: Disassociate the thread from the transaction branch;
  7. Xa_forget: allows RM to abandon its knowledge of the heuristic completion transaction branch;
  8. Xa_open: initializes RM for AP use.
  9. Xa_prepare: asks RM to prepare the commit transaction branch;
  10. Xa_recover: obtains the list of Xids prepared or heuristically completed by RM.
  11. Xa_rollback: tells RM to rollback the transaction branch.
  12. Xa_start: Start or resume the transaction branch – associates the XID with the future work of the RM’s thread requests

Two-stage submission

XA specification is based on two-stage commit protocol, which is optimized by XA specification. A two-phase commit is basically a two-phase commit. Here’s an overview of the two-phase commit process:

Phase 1: Pre-commit phase 1. Transaction query: The coordinator will ask all the participant nodes if they can perform commit operation 2. Perform transaction: Each participant performs transaction operations such as resource locking and logging Undo and Redo information to the transaction log 3. The participant gives the coordinator a response to the transaction query: if the participant successfully performs the transaction, the participant gives the coordinator a Yes response, otherwise No response

If the coordinator receives a Yes response from all participants, transaction Commit 1 is executed. Send a Commit request: The coordinator sends a Commit request to the participant. 2. Feedback transaction commit results: The participant sends an Ack message 4 to the coordinator after completing the transaction commit. Completion of transaction: The coordinator completes the transaction after receiving Ack messages from all participants

If any participant gives the coordinator a No response, or if the coordinator has not received feedback from all participants after the wait timeout, transaction 1 is interrupted. Send a Rollback request: the coordinator sends a Rollback request to the participant. 2. Transaction Rollback: The participant uses Undo information to perform transaction Rollback and release transaction resources 3. Feedback transaction rollback result: The participant sends an Ack message 4 to the coordinator after completing the transaction rollback. Interrupt transaction: The coordinator interrupts the transaction after receiving an Ack message from all participants

Because the two-stage submission itself has problems such as blocking and single point, an improved version of three-stage submission emerged later, which divided the first stage into two parts, which will not be introduced in detail here.

After the standard is defined, various RM products need to implement these interfaces, so that distributed transactions can be supported. The most typical RM includes database, MQ, etc. In a distributed transaction, there are often multiple RM. The XA support provided by each RM can be understood as a transaction branch, which is uniformly assigned to TM for management.

Mysql XA support

To check whether Mysql currently provides XA support, use the following command:

Where XA is used to indicate whether it is supported or not, InnoDB engine is supported, others are not;

XA transaction SQL statement

XA {START|BEGIN} xid [JOIN|RESUME]  //Enable XA transaction XAEND xid [SUSPEND [FOR MIGRATE]]  //End XA transaction XAPREPARE xid  //Preparing to commit XACOMMIT xid [ONE PHASE]  //Commit transaction XAROLLBACK xid  //Rollback transaction XA RECOVER//List all of thePREPAREPhase of XA transactionsCopy the code

See Mysql XA documentation for more information

Here is a simple XA transaction that inserts rows into a table as part of a global transaction:

mysql> XA START 'xatest';
Query OK, 0 rows affected (0.00 sec)

mysql> INSERT INTO mytable (i) VALUES(10);
Query OK, 1 row affected (0.04 sec)

mysql> XA END 'xatest';
Query OK, 0 rows affected (0.00 sec)

mysql> XA PREPARE 'xatest';
Query OK, 0 rows affected (0.00 sec)

mysql> XA COMMIT 'xatest';
Query OK, 0 rows affected (0.00 sec)
Copy the code

ActiveMQ XA support

ActiveMQ also provides XA related command support, as shown below:

    public static final byte BEGIN = 0;  // Start the transaction
    public static final byte PREPARE = 1;  // Ready to submit
    public static final byte COMMIT_ONE_PHASE = 2;  // Phase commit
    public static final byte COMMIT_TWO_PHASE = 3;  // Phase 2 commit
    public static final byte ROLLBACK = 4;  // Rollback the transaction
    public static final byte RECOVER = 5;  // Lists all XA transactions in the PREPARE phase
    public static final byte FORGET = 6;  // Allow RM to abandon its understanding of the heuristic completion transaction branch
    public static final byte END = 7;  // End the XA transaction
Copy the code

ActiveMQ expresses different XA interface types through the above byte identifiers.

All types of RM have provided support for XA protocol. To make developers better use of XA protocol, Take Java as an example. Java provides JTA specification, and all types of RM also need to implement JTA specification interfaces.

JTA specification

The Java Transaction API is considered the Java version of the XA specification that provides distributed Transaction capabilities for the JEE platform, as shown in the following diagram:

It can be found that there is an Application Server more than XA specification, which is actually a Web container, such as Tomcat, WebLogic, JBoss, websphere, etc. In addition to Tomcat, several other containers implement the JTA specification and can provide the function of transaction manager. Containers such as Tomcat that do not provide transaction management can use third-party distributed transaction managers such as Atomikos.

Note: The JTA specification does not specify interfaces related to communication. For more details on interoperability between TMS, see the JTS specification;

More: JTA documentation

The interface definition

Java will all transaction specifications are defined in the JTA package, only the interface is not implemented, you can find the latest version of this JAR package 1.1, since 2008 has not been updated, want to see the detailed source code directly introduced can:

<dependency>
	<groupId>javax.transaction</groupId>
	<artifactId>jta</artifactId>
	<version>1.1</version>
</dependency>
Copy the code

The specific source code is shown below, with several core interface classes highlighted in red:

A total of 8 interfaces are as follows:

  1. XAResource: interface that RM needs to implement. Defines the interface that RM provides for TM operations.
  2. Xid: transaction ID;
  3. Status: transaction Status, a total of 10 states;
  4. Sychronization: Synchronization interface;
  5. Transaction: Transaction interface;
  6. TransactionManager: TransactionManager that manages the full life cycle of a transaction
  7. TransactionSynchronizationRegistry: transaction synchronization register;
  8. UserTransaction: a transaction client for the user that encapsulates the interface through which the user can use the transaction;

In fact, these interfaces are not implemented by developers, but by RM and TM manufacturers:

XAResource, Xid interface: implemented by RM vendors, such as database vendors, MQ vendors, etc.

TransactionManager, UserTransaction interface: can be implemented by Web containers such as JBoss, WebLogic, etc., or by third parties such as Atomikos, etc.

RM to realize

Common RMS include database and MQ. The following uses Mysql and AcitveMQ as examples to see how this is used;

The database

In the above chapter, we have introduced Mysql’s support for XA, that is, Mysq manufacturers have provided support for related functions, in fact, the following is to ensure that the driver provides Mysql XA function, and at the same time need to implement XAResource, Xid related interfaces in JTA;

com.mysql.jdbc.jdbc2.optional.MysqlXAConnection   --> XAResource
com.mysql.jdbc.jdbc2.optional.MysqlXid            --> Xid
Copy the code

These are the two core classes supported by JTA in the mysql driver, which are relatively simple to use:

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import javax.sql.XAConnection;
import javax.transaction.xa.XAException;
import javax.transaction.xa.XAResource;
import javax.transaction.xa.Xid;
import com.mysql.jdbc.jdbc2.optional.MysqlXAConnection;
import com.mysql.jdbc.jdbc2.optional.MysqlXid;

public class XAMysql {

	public static void main(String[] args) throws SQLException {
		// Prints XA statements for debugging
		boolean logXaCommands = true;
		Connection conn1 = DriverManager.getConnection("jdbc:mysql://localhost:3306/ds0"."root"."root");
		XAConnection xaConn1 = new MysqlXAConnection((com.mysql.jdbc.ConnectionImpl) conn1, logXaCommands);
		XAResource rm1 = xaConn1.getXAResource();

		Connection conn2 = DriverManager.getConnection("jdbc:mysql://localhost:3306/ds1"."root"."root");
		XAConnection xaConn2 = new MysqlXAConnection((com.mysql.jdbc.ConnectionImpl) conn2, logXaCommands);
		XAResource rm2 = xaConn2.getXAResource();

		// Global transaction ID
		byte[] gid = "global".getBytes();
		int formatId = 1;
		try {
			// Transaction branch 1
			byte[] bqual1 = "b1".getBytes();
			Xid xid1 = new MysqlXid(gid, bqual1, formatId);
			rm1.start(xid1, XAResource.TMNOFLAGS);
			PreparedStatement ps1 = conn1
					.prepareStatement("insert into t_order0 (user_id,order_id) values ('110','1212')");
			ps1.execute();
			rm1.end(xid1, XAResource.TMSUCCESS);

			// Transaction branch 2
			byte[] bqual2 = "b2".getBytes();
			Xid xid2 = new MysqlXid(gid, bqual2, formatId);
			rm2.start(xid2, XAResource.TMNOFLAGS);
			PreparedStatement ps2 = conn2
					.prepareStatement("insert into t_order0 (user_id,order_id) values ('111','1213')");
			ps2.execute();
			rm2.end(xid2, XAResource.TMSUCCESS);

			// Two-phase commit
			int rm1_prepare = rm1.prepare(xid1);
			int rm2_prepare = rm2.prepare(xid2);
			if (rm1_prepare == XAResource.XA_OK && rm2_prepare == XAResource.XA_OK) {
				rm1.commit(xid1, false);
				rm2.commit(xid2, false);
			} else{ rm1.rollback(xid1); rm2.rollback(xid2); }}catch(XAException e) { e.printStackTrace(); }}}Copy the code

The above not only introduces how XAResource is used, but also simply simulates the function of distributed transaction management. Transactions can only be committed when multiple data sources are ready, otherwise the transaction can be rolled back. This part should be handed over to a more professional component to implement.

MQ

There are many MQ vendors. Not all MQ vendors implement JTA interfaces. The following AcitveMQ implements JTA RM interfaces:

org.apache.activemq.TransactionContext      --> XAResource
org.apache.activemq.command.XATransactionId --> Xid
Copy the code

Here is a simple example:

import javax.jms.JMSException;
import javax.jms.XAQueueConnection;
import javax.jms.XAQueueConnectionFactory;
import javax.transaction.xa.XAException;
import javax.transaction.xa.XAResource;
import javax.transaction.xa.Xid;

import org.apache.activemq.ActiveMQXAConnectionFactory;
import org.apache.activemq.ActiveMQXASession;
import org.apache.activemq.TransactionContext;
import org.apache.activemq.command.XATransactionId;

public class MQXATest {

	public static void main(String[] args) throws XAException, JMSException {
		XAQueueConnectionFactory factory = new ActiveMQXAConnectionFactory("tcp://localhost:61616");
		XAQueueConnection qConnection = factory.createXAQueueConnection();
		qConnection.start();
		ActiveMQXASession session = (ActiveMQXASession) qConnection.createXAQueueSession();
		// TransactionContext implements XAResource
		TransactionContext tc = session.getTransactionContext();

		// XATransactionId Implements Xid
		Xid xid = new XATransactionId();
		tc.start(xid, XAResource.TMSUCCESS);
		tc.end(xid, XAResource.TMSUCCESS);
		int prepare = tc.prepare(xid);
		if (prepare == XAResource.XA_OK) {
			tc.commit(xid, false);
		} else{ tc.rollback(xid); }}}Copy the code

The above briefly introduces the common RM vendors’ support for JTA interfaces, which is generally divided into two steps: the first step is that vendors provide support for XA interfaces; the second step is to facilitate Java users to use client programs (such as drivers and client JAR packages) that provide JTA interfaces.

TM implementation

The implementation of transaction manager also mentioned above mainly includes: Web container implementation, third-party implementation;

The web container

JBoss transaction is mainly related to jboss-Transaction and jboss-transaction-spi, and its core classes mainly include:

org.jboss.tm.TxManager                                    --> TransactionManager
org.jboss.tm.usertx.client.ServerVMClientUserTransaction  --> UserTransaction
Copy the code

We will not introduce too much about the configuration here, but we will focus on the third-party implementation, taking Atomikos as an example.

Atomikos

Atomikos is the name of a company that provides an implementation of XA distributed Transaction TM based on the JTA specification, consisting of two products:

  1. TransactionEssentials: Open source, free product;
  2. ExtremeTransactions: Business Edition premium product;

The relationship between the two products is shown in the figure below:

The commercial version offers more additional features:

  • Support FOR TCC: flexible transaction support, try-confirm-cancel;
  • Support transaction propagation through RMI, IIOP, SOAP and other remote procedure call technologies; This can actually be used in common microservices scenarios: multiple applications with multiple data sources;

Atomikos also provides implementations of UserTransaction and TransactionManager interfaces:

com.atomikos.icatch.jta.UserTransactionImp
com.atomikos.icatch.jta.TransactionManagerImp
Copy the code

Let’s look at the use of a simple distributed manager:

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.util.Properties;

import javax.transaction.UserTransaction;

import com.atomikos.icatch.jta.UserTransactionImp;
import com.atomikos.jdbc.AtomikosDataSourceBean;

public class AtomikosTest {

	public static void main(String[] args) {
		AtomikosDataSourceBean ds1 = createAtomikosDataSourceBean("t_order0");
		AtomikosDataSourceBean ds2 = createAtomikosDataSourceBean("t_order1");

		Connection conn1 = null;
		Connection conn2 = null;
		PreparedStatement ps1 = null;
		PreparedStatement ps2 = null;

		UserTransaction userTransaction = new UserTransactionImp();
		try {
			// Start the transaction
			userTransaction.begin();

			// Execute branch 1
			conn1 = ds1.getConnection();
			ps1 = conn1.prepareStatement("insert into t_order0 (user_id,order_id) values ('110','1212')");
			ps1.execute();

			// Execute branch 2
			conn2 = ds2.getConnection();
			ps2 = conn2.prepareStatement("insert into t_order1 (user_id,order_id) values ('111','1213')");
			ps2.execute();

			// Two-phase commit
			userTransaction.commit();
		} catch (Exception e) {
			// Abnormal rollback
			userTransaction.rollback();
		} finally {
			// Close the connection}}private static AtomikosDataSourceBean createAtomikosDataSourceBean(String dbName) {
		Properties p = new Properties();
		p.setProperty("url"."jdbc:mysql://localhost:3306/" + dbName);
		p.setProperty("user"."root");
		p.setProperty("password"."root");

		AtomikosDataSourceBean ds = new AtomikosDataSourceBean();
		ds.setUniqueResourceName(dbName);

		// MySQL driver XAResource implementation class
		ds.setXaDataSourceClassName("com.mysql.jdbc.jdbc2.optional.MysqlXADataSource");
		ds.setXaProperties(p);
		returnds; }}Copy the code

UserTransaction manages the MysqlXADataSource, commits the transaction, and rolls back the transaction. Compared with the previous XAMysql instance manual submission of each RM, can be said to be more convenient and concise;

JTS specifications

As mentioned above, the JTA specification does not specify a communication-related interface. For more details about interoperability between TM’s, the JTS specification is required. Take a look at the official definition:

JTS specifies the implementation of a transaction manager that supports the JTA specification at a high level and implements the Java mapping of the OMG Object Transaction Services (OTS) specification at a low level. JTS uses the CORBA OTS interface for interoperability and portability (that is, co-transportability and portability). These interfaces define a standard mechanism for any implementation that uses IIOP (internetinterorb protocol) to generate and propagate transaction contexts between JTS transaction managers. Note that this also allows the use of other apis on the IIOP transport mechanism; For example, RMI on IIOP is allowed.

JTS personally feels more like a specification for transaction manager implementation, with emphasis on supporting transaction propagation through RMI, IIOP, SOAP and other remote procedure call technologies.

More: JTS documentation

Other implementations

The above focuses on the DTP model, XA specification, Java according to this specification defined JTA specification, convenient Java developers use; As well as around this model of various manufacturers or some third party companies to do a variety of support, to achieve a more general distributed transaction processing mode; Of course, it is also mentioned above that this method is actually more inclined to CP in CAP, which is a strong consistency implementation method. Therefore, in the case of high concurrency, performance is one of the major defects. More and more Internet companies may be more inclined to the final consistency of the distributed transaction scheme, the common scheme is: TCC, transaction message, local transaction table and so on;

TCC

TCC: Try, Confirm, Cancel

Try: indicates resource reservation.

2. Confirm: Confirm an action, like a submission

Cancel: Cancel operation, similar to rollback operation.

In fact, you can find that the process is very similar to the two-phase commit, which is to test first, and then commit or rollback; The difference between the two: 2PC is more resource-oriented (database, MQ, etc.), while TCC can be business-oriented and has a wider scope; In addition, 2PC will lock resources, but TCC can not need to achieve final consistency; Of course, TCC is also more complex to implement and more intrusive to business;

Transaction message

Some MQ support transaction messages such as RocketMQ, where sent messages and other local events need to succeed and fail at the same time. Here’s how it flows:

  1. The producer sends a message “to be confirmed”.
  2. RocketMQ receives the message and performs related save operations, and returns the status to the producer upon success.
  3. If the return received by the producer is SEND_OK, the local transaction will be performed.
  4. According to the result of the local transaction, the producer performs commit or rollback;
  5. If the producer fails to perform the operation in step 4, the server sends a backcheck request to the message whose status is “to be acknowledged” within a fixed period of time.
  6. After receiving the callback request, the producer returns COMMIT or ROLLBACK according to the result of the local transaction.
  7. After receiving the result, the server performs related operations.

You can see that RocketMQ also implements final consistency;

Local transaction table

Local transaction table: using the local transactions of each system to achieve distributed transactions; Break big things down into smaller ones;

Putting local business and message insertion operations into the message table in the same transaction guarantees success and failure in the local transaction.

Next, MQ can be used to subscribe to messages and listen to them, automatically triggering events when there are messages; Or periodic polling scan to check the data in the message table;

The consumer side had better ensure idempotency to prevent repeated notifications;

A phase

Stage 1: Simple understanding is that if multiple data sources operate, then submit one by one, which often occurs in the case of single system and multiple data sources; This pattern is possible for transaction inconsistencies in special cases; Spring – data – ChainedTransactionManager it provides similar functionality in common: chain transaction; If this mode is in some internal systems, the network and hardware environment is generally stable, the probability of hardware failure is small, you can try;

Seata

An open source distributed transaction solution provided by Ali is committed to providing high-performance and easy-to-use distributed transaction services under the micro-service architecture.

Seata is an open source distributed transaction solution dedicated to providing high performance and easy to use distributed transaction services. Seata will provide users with AT, TCC, SAGA and XA transaction modes to create a one-stop distributed solution for users.

Here is no more introduction, the official documentation is very comprehensive;

More: Seata

conclusion

This article gives a brief introduction to the points involved in distributed transactions, which can be viewed as an outline. Many of the points can only be found when they are actually used. Distributed transaction can be said to be a difficult problem in all technologies, and there are many solutions, which need to make the most appropriate choice according to the actual situation of the business. This process is actually quite difficult, you need to understand the advantages and disadvantages of each solution, and its applicable scope. There is no universal solution.

Thank you for attention

You can pay attention to the wechat public account “Roll back the code”, read the first time, the article continues to update; Focus on Java source code, architecture, algorithms, and interviews.