Distributed Transaction -Seata

SEAT


  • Article Directory

1. What is Seata?

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

2. Development history

Ants Gold service:

  • Xts: Extended Transaction Service. Ants gold dress middleware team since 2007 to develop a distributed transaction middleware, the middleware is widely used in gold suit ant services to address the problem of data consistency between the databases and services.

  • Dtx: Distributed Transaction expansion. Since 2013, XTS has to DTX names published on ants gold dress cloud.

Ali Baba:

  • TXC: Alibaba middleware team since 2014 to start the project, in order to solve the problems caused by a distributed transaction application architecture from a single service to micro shift caused

  • GTS: Global Transaction Services. Txc as a new name GTS Ali cloud middleware products released in 2016

  • Fescar: From 2019 we started an open source project Fescar based txc / gts in order to work closely with the community in the future

  • Seata: simple and scalable architecture autonomous transaction. Ants joined Fescar gold dress, making it a more neutral and open distributed trading community, while Fescar been renamed Seata

3. Micro-distributed transaction service in question

Scene conventional single application - electricity supplier shopping. Its business consists of three modules (inventory, orders and account), these three modules using the respective local data source.

In the course of business occurs, the local transaction to ensure data consistency.

Micro-services architecture has changed. The above-mentioned three modules are designed on the three different sources of three services (Mode: database for each service). Local affairs naturally ensures data consistency for each service.

4. Seata how to resolve distributed transactions?

4.1 Seata design principles to solve the distributed transaction:

4.2 How to define a distributed transaction:

Distributed transactions are global transactions by a group consisting of affairs branch, that branch transaction is a local transaction.

4.3 Seata There are three basic components:

  • Transaction Coordinator (TC): Maintenance and global affairs branch of the state, drive global commit or rollback.
  • Transaction Manager (TM): the definition of a global transaction scope: Start the global transaction, the global transaction is committed or rolled back.
  • Resource Manager (RM): Resource Management Branch affairs, TC communicate with to register and report the transaction branch branch of state affairs,

4.4 Seata management of distributed transactions typical life cycle:

  • TM TC required to start a new global transaction. TC generates an XID global transaction.

  • XID micro propagation by calling chain services.

  • RM will be registered as a local transaction XID to the appropriate branch of the global transaction TC.

  • TM claim TC corresponding global transaction commit or rollback the XID.

  • TC transaction driving all the branches in the XID respective global transaction to commit or rollback for branching.

5. SpringCloud integrated Seata

github source reference address

5.1 running Seata

5.1.1 Seata Download https://github.com/seata/seata/releases

5.1.2 Seata profile

seata server configuration are all in the conf file folder, inside that folder there are two files we have to be described in detail below.

seata server default file (papers) to store transaction logs, run the transaction information, we can be specified by the form -m db script parameters, currently only supports file, db both.

file.conf

The configuration file is used to store mode, transaction information NIO transparent transmission information, the default mode corresponding file registry.conf file configuration.

registry.conf

seata server core configuration file, you can configure the service by way of the registration file, read configuration mode.

Sign up mode currently supports file, nacos, eureka, redis, zk, consul, etcd3, sofa, etc., default file, registration information in a manner corresponding to file.conf read.

Reads the configuration information way to support file, nacos, apollo, zk, consul, etcd3 etc., default file, read the corresponding configuration file in file.conf.

5.1.3 Run Seata

Windows environment

seata-server.bat -p 8091 -m file

Linux environment

sh seata-server.sh -p 8091 -m file                       #以前台运行方式运行seata

nohup sh seata-server.sh -p 8091 -h 127.0.0.1 -m file &> seata.log &            #以后台方运行式启动seata

-host -h host number specified binding, the default 0.0.0.0

-port -p Specifies the listening port number, default 8091

-storeMOde -m log storage (file, db), the default file

5.2 initialization script sql

# Account
DROP SCHEMA IF EXISTS db_account;
CREATE SCHEMA db_account;
USE db_account;

CREATE TABLE `account_tbl`
(
    `id`      INT(11) NOT NULL AUTO_INCREMENT,
    `user_id` VARCHAR(255) DEFAULT NULL,
    `money`   INT(11)      DEFAULT 0,
    PRIMARY KEY (`id`)
) ENGINE = InnoDB
  DEFAULT CHARSET = utf8;

INSERT INTO account_tbl (id, user_id, money)
VALUES (1, '1001', 10000);
INSERT INTO account_tbl (id, user_id, money)
VALUES (2, '1002', 10000);

CREATE TABLE `undo_log` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `branch_id` bigint(20) NOT NULL,
  `xid` varchar(100) NOT NULL,
  `context` varchar(128) NOT NULL,
  `rollback_info` longblob NOT NULL,
  `log_status` int(11) NOT NULL,
  `log_created` datetime NOT NULL,
  `log_modified` datetime NOT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `ux_undo_log` (`xid`,`branch_id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;

# Order
DROP SCHEMA IF EXISTS db_order;
CREATE SCHEMA db_order;
USE db_order;

CREATE TABLE `order_tbl`
(
    `id`             INT(11) NOT NULL AUTO_INCREMENT,
    `user_id`        VARCHAR(255) DEFAULT NULL,
    `commodity_code` VARCHAR(255) DEFAULT NULL,
    `count`          INT(11)      DEFAULT '0',
    `money`          INT(11)      DEFAULT '0',
    PRIMARY KEY (`id`)
) ENGINE = InnoDB
  DEFAULT CHARSET = utf8;

CREATE TABLE `undo_log` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `branch_id` bigint(20) NOT NULL,
  `xid` varchar(100) NOT NULL,
  `context` varchar(128) NOT NULL,
  `rollback_info` longblob NOT NULL,
  `log_status` int(11) NOT NULL,
  `log_created` datetime NOT NULL,
  `log_modified` datetime NOT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `ux_undo_log` (`xid`,`branch_id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;

# Storage
DROP SCHEMA IF EXISTS db_storage;
CREATE SCHEMA db_storage;
USE db_storage;

CREATE TABLE `storage_tbl`
(
    `id`             INT(11) NOT NULL AUTO_INCREMENT,
    `commodity_code` VARCHAR(255) DEFAULT NULL,
    `count`          INT(11)      DEFAULT '0',
    PRIMARY KEY (`id`),
    UNIQUE KEY `commodity_code` (`commodity_code`)
) ENGINE = InnoDB
  DEFAULT CHARSET = utf8;


INSERT INTO storage_tbl (id, commodity_code, count)
VALUES (1, '2001', 1000);

CREATE TABLE `undo_log` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `branch_id` bigint(20) NOT NULL,
  `xid` varchar(100) NOT NULL,
  `context` varchar(128) NOT NULL,
  `rollback_info` longblob NOT NULL,
  `log_status` int(11) NOT NULL,
  `log_created` datetime NOT NULL,
  `log_modified` datetime NOT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `ux_undo_log` (`xid`,`branch_id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;

5.3 Project Structure

  • order-servie order service
  • business-service merchant services
  • order-service orders Service
  • storage-service warehousing services

5.4 introduced maven dependent

<dependency>
    <groupId>io.seata</groupId>
    <artifactId>seata-all</artifactId>
    <version>1.1.0</version>
</dependency>
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context</artifactId>
    <version>5.0.4.RELEASE</version>
</dependency>
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>8.0.11</version>
</dependency>
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-openfeign</artifactId>
    <version>2.0.0.RELEASE</version>
</dependency>
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
    <version>2.0.0.RELEASE</version>
</dependency>

5.5 configuration files

file.conf of service.vgroup_mapping configuration must be consistent and spring.application.name
in org.springframework.cloud.alibaba.seata.GlobalTransactionAutoConfiguration class org.springframework.cloud:spring-cloud-starter-alibaba-seata, the default will be used $ {spring.application.name} -fescar-service- group name registered as a service to the Seata Server, and if file.conf configuration inconsistencies, will prompt no available server to connect error

You may, but must be configured consistent spring.cloud.alibaba.seata.tx-service-group modified suffix configuration and file.conf

application.properties

spring.application.name=account-service
server.port=8083
spring.datasource.url=jdbc:mysql://localhost:3306/db_account?useSSL=false&serverTimezone=UTC
spring.datasource.username=root
spring.datasource.password=root
spring.jpa.show-sql=true
spring.cloud.alibaba.seata.tx-service-group=my_group

file.conf

service {
  vgroupMapping.my_group = "account-service"
  account-service.grouplist = "127.0.0.1:8091"
  enableDegrade = false
  disableGlobalTransaction = false
}

5.6 start the project, shown below prove successful start:

5.7 Test:

No error was successfully submitted:

curl http://127.0.0.1:8084/purchase/commit

After the completion of the database can be seen in account_tbl id is money 1 will be reduced 5, order_tbl will add a record, storage_tbl id for the reduction in the count field 1 1

Abnormal transaction is rolled back:

curl http://127.0.0.1:8084/purchase/rollback

At this account-service throws an exception, a rollback occurs, the data in the database does not change until after completion of a successful rollback

6. SpringCloud integrated Seata + Nacos

github source reference address

6.1 running Seata

6.1.1 edit the configuration file conf / registry.conf

Note: serverAddr not with 'http: //' prefix

registry {
  # file 、nacos 、eureka、redis、zk、consul、etcd3、sofa
  type = "nacos"

  nacos {
    serverAddr = "114.55.34.44"
    namespace = ""
    cluster = "default"
  }
}
config {
  # file、nacos 、apollo、zk、consul、etcd3
  type = "nacos"
  nacos {
    serverAddr = "114.55.34.44"
    namespace = ""
    cluster = "default"
  }
}

6.1.2 edit the configuration file conf / nacos-config.txt (seata-service-1.1.0 version only or less)

service.vgroup_mapping. Y The in r s e r v i c e g r in The p = d e f a in l t in between of {Your-service-gruop} = default, intermediate {your-service-gruop} own name for the service group definition, application.properties configuration file service in the service group name.

There are two services demo, and are storage-service order-service, so the configuration is as follows:

service.vgroup_mapping.storage-service-group=default
service.vgroup_mapping.order-service-group=default

Initialization seata of nacos configuration:

cd conf
sh nacos-config.sh 114.55.34.44  #114.55.34.44为nacos的服务器地址

seata-service-1.1.0 release adds configuration in Nacos manual:

service.vgroupMapping.storage-service-group=default
service.vgroupMapping.order-service-group=default

Start seata-service:

cd bin
sh seata-server.sh -p 8091 -m file

After a successful start-up display as follows:

6.1.3 initialization sql script

-- 创建 order库、业务表、undo_log表
create database seata_order;
use seata_order;

DROP TABLE IF EXISTS `order_tbl`;
CREATE TABLE `order_tbl` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `user_id` varchar(255) DEFAULT NULL,
  `commodity_code` varchar(255) DEFAULT NULL,
  `count` int(11) DEFAULT 0,
  `money` int(11) DEFAULT 0,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

CREATE TABLE `undo_log`
(
  `id`            BIGINT(20)   NOT NULL AUTO_INCREMENT,
  `branch_id`     BIGINT(20)   NOT NULL,
  `xid`           VARCHAR(100) NOT NULL,
  `context`       VARCHAR(128) NOT NULL,
  `rollback_info` LONGBLOB     NOT NULL,
  `log_status`    INT(11)      NOT NULL,
  `log_created`   DATETIME     NOT NULL,
  `log_modified`  DATETIME     NOT NULL,
  `ext`           VARCHAR(100) DEFAULT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `ux_undo_log` (`xid`, `branch_id`)
) ENGINE = InnoDB
  AUTO_INCREMENT = 1
  DEFAULT CHARSET = utf8;


-- 创建 storage库、业务表、undo_log表
create database seata_storage;
use seata_storage;

DROP TABLE IF EXISTS `storage_tbl`;
CREATE TABLE `storage_tbl` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `commodity_code` varchar(255) DEFAULT NULL,
  `count` int(11) DEFAULT 0,
  PRIMARY KEY (`id`),
  UNIQUE KEY (`commodity_code`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

CREATE TABLE `undo_log`
(
  `id`            BIGINT(20)   NOT NULL AUTO_INCREMENT,
  `branch_id`     BIGINT(20)   NOT NULL,
  `xid`           VARCHAR(100) NOT NULL,
  `context`       VARCHAR(128) NOT NULL,
  `rollback_info` LONGBLOB     NOT NULL,
  `log_status`    INT(11)      NOT NULL,
  `log_created`   DATETIME     NOT NULL,
  `log_modified`  DATETIME     NOT NULL,
  `ext`           VARCHAR(100) DEFAULT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `ux_undo_log` (`xid`, `branch_id`)
) ENGINE = InnoDB
  AUTO_INCREMENT = 1
  DEFAULT CHARSET = utf8;

-- 初始化库存模拟数据
INSERT INTO seata_storage.storage_tbl (id, commodity_code, count) VALUES (1, 'product-1', 9999999);
INSERT INTO seata_storage.storage_tbl (id, commodity_code, count) VALUES (2, 'product-2', 0);

6.1.4 introduced maven dependent

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <optional>true</optional>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-test</artifactId>
    <scope>test</scope>
</dependency>
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>

<!-- nacos -->
<dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
    <version>0.2.1.RELEASE</version>
</dependency>

<!-- seata-->
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-alibaba-seata</artifactId>
    <version>2.1.0.RELEASE</version>
</dependency>
<dependency>
    <groupId>io.seata</groupId>
    <artifactId>seata-all</artifactId>
    <version>1.1.0</version>
</dependency>

<!-- mysql -->
<dependency>
    <groupId>com.work</groupId>
    <artifactId>base-framework-mysql-support</artifactId>
    <version>1.0-SNAPSHOT</version>
</dependency>

6.1.5 Profile registy.conf

registry {
  # file 、nacos 、eureka、redis、zk、consul、etcd3、sofa
  type = "nacos"

  nacos {
    serverAddr = "114.55.34.44"
    namespace = ""
    cluster = "default"
  }
}
config {
  # file、nacos 、apollo、zk、consul、etcd3
  type = "nacos"
  nacos {
    serverAddr = "114.55.34.44"
    namespace = ""
    cluster = "default"
  }
}

6.1.6 Profile application.properties

order-service

spring.application.name=order-service
server.port=9091

# Nacos 注册中心地址
spring.cloud.nacos.discovery.server-addr = 114.55.34.44:8848

# seata 服务分组,要与服务端nacos-config.txt中service.vgroup_mapping的后缀对应
spring.cloud.alibaba.seata.tx-service-group=order-service-group
logging.level.io.seata = debug

# 数据源配置
spring.datasource.druid.url=jdbc:mysql://114.55.34.44:3306/seata_order?allowMultiQueries=true
spring.datasource.druid.driverClassName=com.mysql.jdbc.Driver
spring.datasource.druid.username=root
spring.datasource.druid.password=root

storage-service

spring.application.name=storage-service
server.port=9092

# Nacos 注册中心地址
spring.cloud.nacos.discovery.server-addr = 114.55.34.44:8848

# seata 服务分组,要与服务端nacos-config.txt中service.vgroup_mapping的后缀对应
spring.cloud.alibaba.seata.tx-service-group=storage-service-group
logging.level.io.seata = debug

# 数据源配置
spring.datasource.druid.url=jdbc:mysql://114.55.34.44:3306/seata_storage?allowMultiQueries=true
spring.datasource.druid.driverClassName=com.mysql.jdbc.Driver
spring.datasource.druid.username=root
spring.datasource.druid.password=root

6.1.7 Startup Items

6.1.8 Testing

Distributed transaction is successful, simulate normal orders, inventory buckle

curl localhost:9091/order/placeOrder/commit

Distributed transaction fails, analog single success, failure buckle inventory, and ultimately rolled back at the same time

curl localhost:9091/order/placeOrder/rollback

More registration centers and integrated framework, reference documentation

Published 11 original articles · won praise 2 · Views 431

Guess you like

Origin blog.csdn.net/qq_41112063/article/details/105314104