云计算百科
云计算领域专业知识百科平台

分布式事务及其解决方案

1.分布式事务介绍

在分布式系统中,如果一个业务需要多个服务合作完成,而且每一个服务都有事务,多个事务必须同时成功或失败,这样的事务就是分布式事务。其中的每个服务的事务就是一个分支事务。整个业务称为全局事务。
以商场下单业务为例(微服务系统):
在这里插入图片描述
下单业务涉及的创建订单、清理购物车、扣减商品库存3个分支事务必须同时成功或失败,不然就会出现类似没库存但能下单的不合理情况。

2.分布式事务解决思路

解决分布式事务,各个子事务之间必须能感知到彼此的事务状态,才能保证状态一致。
可以引入一个事务协调者,让各个事务感知到彼此的事务状态。
在这里插入图片描述

3.认识Seata

基于上述思路,阿里巴巴开源Seata用于解决分布式事务问题。
Seata事务管理中有三个重要的角色:
• TC (Transaction Coordinator)- 事务协调者:维护全局和分支事务的状态,协调全局事务提交或回滚,一个独立的微服务,需要单独部署。
•TM(Transaction Manager)- 事务管理器:定义全局事务的范围、开始全局事务、提交或回滚全局事务。
• RM(Resource Manager)- 资源管理器:管理分支事务,与TC交谈以注册分支事务和报告分支事务的状态。

TM和RM可以理解为Seata的客户端部分,引入到参与事务的微服务依赖中即可。将来TM和RM就会协助微服务,实现本地分支事务与TC之间交互,实现事务的提交或回滚。在这里插入图片描述

4.部署TC服务

  • 先建表,将资源里面的seata-tc.sql在数据库里面执行
  • 配置文件用资源里面的application.yml即可
  • 将整个seata文件夹解压到服务器根目录,使用docker部署
  • docker run –name seata \\
    -p 8099:8099 \\
    -p 7099:7099 \\
    -e SEATA_IP=192.168.150.101 \\
    -v ./seata:/seata-server/resources \\
    –privileged=true \\
    –network hm-net \\
    -d \\
    seataio/seata-server:1.5.2

    5.微服务集成Seata

    5.1引入依赖

    为了方便各个微服务集成seata,可以把seata配置共享到nacos,因此trade-service模块不仅仅要引入seata依赖,还要引入nacos依赖:

    <!–统一配置管理–>
    <dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
    </dependency>
    <!–读取bootstrap文件–>
    <dependency>
    <groupId>org.springframework.cloud</groupId>
    <artifactId>spring-cloud-starter-bootstrap</artifactId>
    </dependency>
    <!–seata–>
    <dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-seata</artifactId>
    </dependency>

    5.2改造配置

    配置读取顺序:bootstrap 先读,用来连 Nacos;Nacos 远程配置(含共享)在中间;最后读本地 application.yml;本地配置可覆盖远程同名配置。

    nacos

    在nacos上添加一个共享的seata配置,命名为shared-seata.yaml

    seata:
    registry: # TC服务注册中心的配置,微服务根据这些信息去注册中心获取tc服务地址
    type: nacos # 注册中心类型 nacos
    nacos:
    server-addr: 192.168.150.101:8848 # nacos地址
    namespace: "" # namespace,默认为空
    group: DEFAULT_GROUP # 分组,默认是DEFAULT_GROUP
    application: seataserver # seata服务名称
    username: nacos
    password: nacos
    tx-service-group: hmall # 事务组名称
    service:
    vgroup-mapping: # 事务组与tc集群的映射关系
    hmall: "default"

    bootstrap.yml

    改造trade-service模块,添加bootstrap.yaml

    spring:
    application:
    name: tradeservice # 服务名称
    profiles:
    active: dev
    cloud:
    nacos:
    server-addr: 192.168.150.101 # nacos地址
    config:
    file-extension: yaml # 文件后缀名
    shared-configs: # 共享配置
    dataId: sharedjdbc.yaml # 共享mybatis配置
    dataId: sharedlog.yaml # 共享日志配置
    dataId: sharedswagger.yaml # 共享日志配置
    dataId: sharedseata.yaml # 共享seata配置

    5.3添加数据库表

    seata的客户端在解决分布式事务的时候需要记录一些中间数据,保存在数据库中。因此要先准备一个undo_log表。

    — for AT mode you must to init this sql for you business database. the seata server not need it.
    CREATE TABLE IF NOT EXISTS `undo_log`
    (
    `branch_id` BIGINT NOT NULL COMMENT 'branch transaction id',
    `xid` VARCHAR(128) 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 = utf8mb4 COMMENT ='AT transaction mode undo table';

    5.4修改分布式事务注解

    将下单业务方法上的@Transactional注解改为Seata提供的@GlobalTransactional。
    @GlobalTransactional注解就是在标记事务的起点,将来TM就会基于这个方法判断全局事务范围,初始化全局事务。

    6.Seata的XA模式

    实现前提:
    配置文件添加配置

    seata:
    data-source-proxy-mode: XA

    一阶段:

    • 事务协调者通知每个事务参与者执行本地事务
    • 本地事务执行完成后报告事务执行状态给事务协调者,此时事务不提交,继续持有数据库锁

    二阶段:

    • 事务协调者基于一阶段的报告来判断下一步操作
    • 如果一阶段都成功,则通知所有事务参与者,提交事务
    • 如果一阶段任意一个参与者失败,则通知所有事务参与者回滚事务
      在这里插入图片描述

    7.seata的AT模式

    实现前提:
    完成5.3数据库添加undo_log表,配置文件可以不添加配置(seata默认就是AT模式)

    阶段一RM的工作:

    • 注册分支事务
    • 记录undo-log(数据快照)
    • 执行业务sql并提交
    • 报告事务状态
      阶段二提交时RM的工作:
    • 删除undo-log即可
      阶段二回滚时RM的工作:
    • 根据undo-log恢复数据到更新前
      在这里插入图片描述

    8.XA和AT模式的区别

    • XA模式一阶段不提交事务,锁定资源;AT模式一阶段直接提交,不锁定资源。
    • XA模式依赖数据库机制实现回滚;AT模式利用数据快照实现数据回滚。
    • XA模式强一致;AT模式最终一致
    赞(0)
    未经允许不得转载:网硕互联帮助中心 » 分布式事务及其解决方案
    分享到: 更多 (0)

    评论 抢沙发

    评论前必须登录!