Spring CloudMicroservice微服务springcloud

微服务架构 | 11.1 整合 Seata AT 模式实现分布式

2022-02-09  本文已影响0人  多氯环己烷

前言

参考资料
《Spring Microservices in Action》
《Spring Cloud Alibaba 微服务原理与实战》
《B站 尚硅谷 SpringCloud 框架开发教程 周阳》
《Seata 中文官网》
《Seata GitHub 官网》
《Seata 官方示例》

Seata 是一款开源的分布式事务解决方案,致力于在微服务架构下提供高性能和简单易用的分布式事务服务;它提供了 AT、TCC、Saga 和 XA 事务模式,为开发者提供了一站式的分布式事务解决方案;


1. Seata 基础知识

1.1 Seata 的 AT 模式

1.2 Seata AT 模式的工作流程

Seata AT 模式的工作流程.png

1.3 Seata 服务端的存储模式

1.4 Seata 与 Spring Cloud 整合说明

1.5 关于事务分组的说明

事务分组的实现原理.png

2. Seata 服务端的安装

Seata 安装的是 AT 模型中的 TC,为方便理解这里称为服务端;
Seata 作为一个事务中间件,有很多种部署安装方式,有安装包部署、源码部署和 Docker 部署,这里介绍前两种。版本选 1.4.2;

2.1 安装包安装 Seata

2.1.1 下载 Seata

下载 Seata.png

2.1.2 修改存储模式为 db

-- 判断数据库存在,存在再删除
DROP DATABASE IF EXISTS seata;
    
-- 创建数据库,判断不存在,再创建
CREATE DATABASE IF NOT EXISTS seata;

-- 使用数据库
USE seata;

-- the table to store GlobalSession data
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;

-- the table to store BranchSession data
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;

-- the table to store lock data
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;

2.1.3 指明注册中心与配置中心,上传 Seata 配置

2.1.4 启动 Seata 服务器

在 Nacos 服务器里能看见 Seata 服务.png

2.2 源码安装 Seata

2.2.1 拉取代码

Seata GitHub.png

2.2.2 修改配置文件

2.2.3 启动服务

Seata 源码启动成功.png 在 Nacos 服务器里能看见 Seata 服务.png

3. Spring Cloud 集成 Seata 实现分布式事务

3.1 引入 pom.xml 依赖文件

<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-seata</artifactId>
</dependency>

3.2 修改 bootstrap.yml 配置文件

3.3 注入数据源

@Configuration
public class DataSourceProxyConfig {

    @Bean
    @ConfigurationProperties(prefix = "spring.datasource")
    public DataSource dataSource() {
        return new DruidDataSource();
    }

    @Bean
    public DataSourceProxy dataSourceProxy(DataSource dataSource) {
        return new DataSourceProxy(dataSource);
    }

    @Bean
    public SqlSessionFactory sqlSessionFactoryBean(DataSourceProxy dataSourceProxy) throws Exception {
        SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
        sqlSessionFactoryBean.setDataSource(dataSourceProxy);
        return sqlSessionFactoryBean.getObject();
    }
}

3.4 添加 undo_log 表

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

3.5 使用 @GlobalTransactional 开启事务

4. Seata AT 模式的实现原理

4.1 两个阶段

4.2 AT 模式第一阶段实现原理

4.3 AT 模式第二阶段实现原理

4.3.1 事务提交

4.3.2 事务回滚

4.4 关于事务的隔离性保证

4.4.1 写隔离

4.4.2 读隔离


最后

\color{blue}{\rm\small{新人制作,如有错误,欢迎指出,感激不尽!}}

\color{blue}{\rm\small{欢迎关注我,并与我交流!}}

\color{blue}{\rm\small{如需转载,请标注出处!}}

上一篇下一篇

猜你喜欢

热点阅读