Distributed transactions and Seata

Distributed transaction overview

In the microservice architecture, different services have their own independent databases. In the past, the transaction control of a single application is based on the connection, that is, all operations are one transaction after each connection to the database. This is obviously not applicable in distributed microservices, because multiple databases cause a transaction to have multiple database connections. At this time, transactions need to be processed distributed

Seata

summary

Seata's full name is Simple Extensible Autonomous Transaction Architecture, that is, simple and extensible autonomous transaction architecture. Seata is a high-performance, easy-to-use distributed transaction solution for microservice architecture. It supports XA, TCC(MT), AT and SAGA transaction modes
In Seata's view, a distributed transaction is a global transaction composed of a batch of branch transactions. Usually, a branch transaction is a local transaction (that is, a transaction controlled through a database connection)

Seata solutions for distributed transactions

  • TC(Transaction Coordinator): a transaction coordinator, which maintains the status of global and branch transactions and drives the submission or rollback of global transactions. It is provided by Seata
  • TM(Transaction Manager): transaction manager, which defines the scope of global transactions: start global transactions, commit or roll back global transactions, which are specified by the developer (annotate where the transaction starts)
  • RM(Resource Manager): a resource manager, which manages the resources of branch transactions, talks with TC to register branch transactions and report the status of branch transactions, and drives branch transaction submission or rollback

Seata solves distributed transactions - AT mode

  1. Download address
  2. Configuration of registry and configuration center: open Seata / conf / registry Conf, change the type of registry to nacos, configure nacos, and change config to file (configured with local file)
  3. Database configuration: open file Conf, change the mode to db, and configure the database connection
  4. Create a new database, seata, and create the following three tables in the database
-- Global table
CREATE TABLE IF NOT EXISTS `global_table`
(
    `xid`                       VARCHAR(128) NOT NULL,
    `transaction_id`            BIGINT,
    `status`                    TINYINT      NOT NULL,
    `application_id`            VARCHAR(32),
    `transaction_service_group` VARCHAR(32),
    `transaction_name`          VARCHAR(128),
    `timeout`                   INT,
    `begin_time`                BIGINT,
    `application_data`          VARCHAR(2000),
    `gmt_create`                DATETIME,
    `gmt_modified`              DATETIME,
    PRIMARY KEY (`xid`),
    KEY `idx_gmt_modified_status` (`gmt_modified`, `status`),
    KEY `idx_transaction_id` (`transaction_id`)
) ENGINE = InnoDB
  DEFAULT CHARSET = utf8;

-- Branch table
CREATE TABLE IF NOT EXISTS `branch_table`
(
    `branch_id`         BIGINT       NOT NULL,
    `xid`               VARCHAR(128) NOT NULL,
    `transaction_id`    BIGINT,
    `resource_group_id` VARCHAR(32),
    `resource_id`       VARCHAR(256),
    `branch_type`       VARCHAR(8),
    `status`            TINYINT,
    `client_id`         VARCHAR(64),
    `application_data`  VARCHAR(2000),
    `gmt_create`        DATETIME(6),
    `gmt_modified`      DATETIME(6),
    PRIMARY KEY (`branch_id`),
    KEY `idx_xid` (`xid`)
) ENGINE = InnoDB
  DEFAULT CHARSET = utf8;

-- Global lock
CREATE TABLE IF NOT EXISTS `lock_table`
(
    `row_key`        VARCHAR(128) NOT NULL,
    `xid`            VARCHAR(128),
    `transaction_id` BIGINT,
    `branch_id`      BIGINT       NOT NULL,
    `resource_id`    VARCHAR(256),
    `table_name`     VARCHAR(32),
    `pk`             VARCHAR(36),
    `gmt_create`     DATETIME,
    `gmt_modified`   DATETIME,
    PRIMARY KEY (`row_key`),
    KEY `idx_branch_id` (`branch_id`)
) ENGINE = InnoDB
  DEFAULT CHARSET = utf8;
  1. Add the following table to each database participating in the transaction
CREATE TABLE IF NOT EXISTS `undo_log`
(
    `branch_id`     BIGINT(20)   NOT NULL COMMENT 'branch transaction id',
    `xid`           VARCHAR(100) NOT NULL COMMENT 'global transaction id',
    `context`       VARCHAR(128) NOT NULL COMMENT 'undo_log context,such as serialization',
    `rollback_info` LONGBLOB     NOT NULL COMMENT 'rollback info',
    `log_status`    INT(11)      NOT NULL COMMENT '0:normal status,1:defense status',
    `log_created`   DATETIME(6)  NOT NULL COMMENT 'create datetime',
    `log_modified`  DATETIME(6)  NOT NULL COMMENT 'modify datetime',
    UNIQUE KEY `ux_undo_log` (`xid`, `branch_id`)
) ENGINE = InnoDB
  AUTO_INCREMENT = 1
  DEFAULT CHARSET = utf8 COMMENT ='AT transaction mode undo table';
  1. Start nacos first, then start seata, and check whether seata is registered successfully
  2. Add the spring cloud starter Alibaba Seata dependency to the service
  3. In file Add the following configuration to conf to file Conf and registry Conf is copied to each project class path, and each service must configure its own local transaction
service{
# Transaction group, my_tx_group is the name of a user-defined transaction group. Branch transactions of the same transaction group form a global transaction
vgroupMapping.my_tx_group = "default"
# Address of seata service
default.grouplist = "127.0.0.1:8091"
# Open global transaction
disableGlobalTransaction = false
}
  1. In application Configuring the transaction group of seata in YML
spring:
  cloud:
    alibaba:
     seata:
       tx-service-group: my_tx_group
  1. Add annotation @ GlobalTransactionl on the method of transaction opening

The above 1 ~ 6 are configured TC, 7 ~ 8 are configured RM, and 9 are designated TM

AT mode workflow

  1. TM requests TC to start a global transaction, and TC will generate a XID to represent the global transaction
  2. XID is propagated to each RM through the service call chain
  3. RM registers the local transaction with TC as a branch transaction through XID
  4. * * exception occurs (after Spring integrates mybatis, transaction rollback means that when a Runtime Exception or Error is caught, Spring will package various underlying database operation exceptions into a DataAccessException) * * or when the transaction is completed, TM will request TC to rollback or submit the corresponding transaction through XID
  5. TC drives all branch transactions registered through the corresponding XID to complete branch commit or rollback

Working mechanism of data rollback

Undo at the beginning of the transaction_ The original data image will be saved in the log. When the transaction is rolled back, the data will be recovered through the image in the log table. After that, undo_ The data in the log will be deleted automatically

Distributed transaction solution

Two phase Submission Scheme Based on XA protocol

  1. Application: an application that uses DTP (distributed transaction processing)
  2. RM: resource manager. The application controls the resources through the resource manager. The resources must implement the interface defined by XA
  3. TM: transaction manager, provided by a third party, responsible for coordinating and managing transactions, turning the programs provided to applications into interfaces, and managing resource managers

Workflow

  1. The first stage is the preparation stage. All participants feed back the information on the success of the transaction to the coordinator
  2. The second stage is the submission stage. The coordinator notifies all participants according to the feedback of all participants, and submits or rolls back on all branches in a consistent manner

All transactions are committed or rolled back at the same time. During the first stage of preparation, the transaction is suspended, resulting in low performance

Three stage Submission Scheme Based on TCC (try confirm cancel) protocol


The try part completes the business preparation and judges whether the transaction can be started; Confirm part completes the business submission; The cancel part completes the rollback of the business (confirm and cancel are the reverse compensation of the transaction)

Advantages and disadvantages of TCC

advantage:

Compared with the two-phase commit, the three-phase commit mainly solves the single point of failure problem and reduces the blocking time, because once the participants cannot receive the coordinator's information in time, they will execute the commit by default, instead of holding the transaction resources uniformly and being blocked

shortcoming

  1. It is highly intrusive to applications, and each branch of business logic must implement three operations: try, confirm and cancel, with high transformation cost
  2. It is difficult to implement. Different rollback strategies need to be practiced according to different failure causes such as network status and system failure. In order to meet the requirements of consistency, confirm and cencel must implement idempotent

MQ based final consistency scheme


Ensure the final consistency of upstream and downstream application data operations through message middleware. Put the local operation and message sending into one transaction (rabbitMQ does not support transaction messages, and consider using rocketMQ) to ensure that both local operation and message sending succeed or fail.
In essence, it is to convert distributed transactions into two local transactions, and then rely on the retry mechanism of downstream services to achieve final consistency.
If the downstream is unsuccessful, consider saving the upstream original image, and schedule a task to judge whether the downstream is successful. If not, recover the upstream data

Keywords: Database Distribution

Added by christophe on Tue, 14 Dec 2021 21:03:15 +0200