十六、SpringCloud Alibaba Seata 处理分布式事务


一、SpringCloud 微服务基础介绍
二、SpringCloud 微服务项目构建
三、SpringCloud 微服务之Eureka 服务注册与发现
四、SpringCloud 微服务之 Zookeeper 服务注册与发现
五、SpringCloud 微服务之Consul 服务注册与发现
六、SpringCloud 微服务之 Ribbon 负载均衡服务调用
七、SpringCloud 微服务之 OpenFeign 服务接口调用
八、SpringCloud 微服务之 Hystrix 断路器
九、Spring Cloud 微服务之 Gateway
十、SpringCloud 微服务之SpringCloud Config 分布式配置中心
十一、SpringCloud 微服务之SpringCloud Bus 消息总线
十二、SpringCloud 微服务之SpringCloud Stream 消息驱动
十三、Spring Cloud 微服务之 SpringCloud Sleuth 分布式请求链路跟踪
十四、SpringCloud Alibaba Nacos 服务注册和配置中心
十五、SpringCloud Alibaba Sentinel 实现熔断与限流
十六、SpringCloud Alibaba Seata 处理分布式事务

1. 分布式事务问题

1.1 分布式之前

单机库存没有这个问题
从 1:1 -> 1:N -> N:N

1.2 分布式之后

单体应用被拆分成微服务应用,
原来的三个模块被拆分成三个独立的应用,分别使用三个独立的数据源,业务操作需要调用三个服务来完成,此时每个服务内部的数据一致性由本地事务来保证,但是全局的数据一致性问题没法保证
在这里插入图片描述

一次业务操作需要垮多个数据源或需要垮多个系统进行远程调用,就会产生分布式事务问题

2. Seata简介

官网:http://seata.io/zh-cn/
官方文档:http://seata.io/zh-cn/docs/overview/what-is-seata.html
下载地址:http://seata.io/zh-cn/blog/download.html

2.1 是什么

Seata 是一款开源的分布式事务解决方案,致力于提供高性能和简单易用的分布式事务服务。Seata 将为用户提供了 AT、TCC、SAGA 和 XA 事务模式,为用户打造一站式的分布式解决方案。

2.2 能做什么

  • 一个典型的分布式事务过程
    • 分布式事务处理过程 - ID + 三组件模型
      • Transaction ID(XID)
        全局唯一的事务ID
      • 三组件概念
        • TC (Transaction Coordinator) - 事务协调者
          维护全局和分支事务的状态,驱动全局事务提交或回滚。
        • TM (Transaction Manager) - 事务管理器
          定义全局事务的范围:开始全局事务、提交或回滚全局事务。
        • RM (Resource Manager) - 资源管理器
          管理分支事务处理的资源,与TC交谈以注册分支事务和报告分支事务的状态,并驱动分支事务提交或回滚。
    • 处理过程
    1. TM 向 TC 申请开启一个全局事务,全局事务创建成功并生成一个全局唯一的 XID;
    2. XID 在微服务调用链路的上下文中传播;
    3. RM 向 TC 注册分支事务,将其纳入 XID 对应全局事务的管辖;
    4. TM 向 TC 发起针对 XID 的全局提交或回滚决议;
    5. TC 调度 XID 下管辖的全部分支事务完成提交或回滚请求。
      在这里插入图片描述

2.3 怎么用

  • 本地 @Transactional
  • 全局 @GlobalTransactional
  • seata的分布式交易解决方案
    在这里插入图片描述

3. Seata-Server安装

  1. 下载地址:http://seata.io/zh-cn/blog/download.html

  2. 将下载的安装包解压到指定目录并修改conf目录下的file.conf配置文件

    1. 先备份原始file.conf文件
    2. 主要修改:自定义事务组名称+事务日志存储模式为db+数据库链接信息
    3. file.conf
      • service模块
        在这里插入图片描述

      • store模块+db

        在这里插入图片描述

  3. 在 mysql 数据库新建库 seata

    CREATE database `seata`;
    
  4. 在 seata库里建表

    -- -------------------------------- The script used when storeMode is 'db' --------------------------------
    -- 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;
    
    CREATE TABLE IF NOT EXISTS `distributed_lock`
    (
        `lock_key`       CHAR(20) NOT NULL,
        `lock_value`     VARCHAR(20) NOT NULL,
        `expire`         BIGINT,
        primary key (`lock_key`)
    ) ENGINE = InnoDB
      DEFAULT CHARSET = utf8mb4;
    
    INSERT INTO `distributed_lock` (lock_key, lock_value, expire) VALUES ('AsyncCommitting', ' ', 0);
    INSERT INTO `distributed_lock` (lock_key, lock_value, expire) VALUES ('RetryCommitting', ' ', 0);
    INSERT INTO `distributed_lock` (lock_key, lock_value, expire) VALUES ('RetryRollbacking', ' ', 0);
    INSERT INTO `distributed_lock` (lock_key, lock_value, expire) VALUES ('TxTimeoutCheck', ' ', 0);
    
  5. 修改 seata/cong目录下的registry.conf配置文件,配置注册信息

    目的是:指明注册中心
    这里配置为 nacos,并配置nacos连接信息
    在这里插入图片描述

  6. 先启动 Nacos 服务,端口号8848

  7. 启动 seata-server

    启动成功后:若启动失败,请查看启动时日志
    在这里插入图片描述

4. 订单/库存/账户业务数据库准备

以下演示都需要先启动Nacos和Seata,保证两个都OK

  • 分布式事务业务说明
    在这里插入图片描述
    下订单 —> 扣库存 —> 减账户(余额)

4.1 创建业务数据库

seata_order:存储订单的数据库
seata_storage:存储库存的数据库
seata_account:存储账户信息的数据库

create database seata_order;
create database seata_storage;
create database seata_account;

4.1 在上述的三个库中分别创建对应的业务表

# seata_order库下新建t_order表
DROP TABLE IF EXISTS `t_order`;
CREATE TABLE `t_order`  (
  `id` bigint(11) NOT NULL AUTO_INCREMENT,
  `user_id` bigint(20) DEFAULT NULL COMMENT '用户id',
  `product_id` bigint(11) DEFAULT NULL COMMENT '产品id',
  `count` int(11) DEFAULT NULL COMMENT '数量',
  `money` decimal(11, 0) DEFAULT NULL COMMENT '金额',
  `status` int(1) DEFAULT NULL COMMENT '订单状态:  0:创建中 1:已完结',
  PRIMARY KEY (`int`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = '订单表' ROW_FORMAT = Dynamic;
# seata_storage库下新建t_storage表
DROP TABLE IF EXISTS `t_storage`;
CREATE TABLE `t_storage`  (
  `id` bigint(11) NOT NULL AUTO_INCREMENT,
  `product_id` bigint(11) DEFAULT NULL COMMENT '产品id',
  `total` int(11) DEFAULT NULL COMMENT '总库存',
  `used` int(11) DEFAULT NULL COMMENT '已用库存',
  `residue` int(11) DEFAULT NULL COMMENT '剩余库存',
  PRIMARY KEY (`int`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = '库存' ROW_FORMAT = Dynamic;
INSERT INTO `t_storage` VALUES (1, 1, 100, 0, 100);
# seata_account库下新建t_account表
CREATE TABLE `t_account`  (
  `id` bigint(11) NOT NULL COMMENT 'id',
  `user_id` bigint(11) DEFAULT NULL COMMENT '用户id',
  `total` decimal(10, 0) DEFAULT NULL COMMENT '总额度',
  `used` decimal(10, 0) DEFAULT NULL COMMENT '已用余额',
  `residue` decimal(10, 0) DEFAULT NULL COMMENT '剩余可用额度',
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8 COLLATE = utf8_general_ci COMMENT = '账户表' ROW_FORMAT = Dynamic;

INSERT INTO `t_account` VALUES (1, 1, 1000, 0, 1000);

4.3 按照上述3库分别建立对应的回滚日志表

订单-库存-账户3个库下都需要建各自独立的回滚日志表

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;

最终效果
在这里插入图片描述

5. 订单/库存/账户业务微服务准备

seata 配置文件:存放到模块的 resources 目录下一份,配置时可以查看
在这里插入图片描述

5.1 新建订单 Order-Module

1. 在父项目中创建 cloud-alibaba-seata-order-service2001 服务module

1.1 pom
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>springcloud</artifactId>
        <groupId>com.zzx</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>cloud-alibaba-seata-order-service2001</artifactId>

    <properties>
        
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值