springcloudAlibaba的学习(八):分布式事务解决方案seata

简介

分布式事务解决方案seata的相关基本概念,环境的搭建和使用

基本概念

事务,一组不可分割的操作,要么全部成功,要么全部失败。有ACID四大特性。

事务分为:本地事务分布式事务
本地事务:程序操作一个数据库的时候,这时的事务就是本地事务,可以使用@Transaction来保证。
分布式事务:操作多个不同节点的数据库,或者是多个服务的操作,这时的事务就是分布式事务。

seata

是一款分布式事务解决方案。提供了AT,TCC,SAGA,和XA事务模式。一般常用的是AT模式。

常见的分布式事务解决方案:

  • seata
  • 消息队列
  • saga
  • xa

一般常见的分布式事务解决方案都是两阶段提交协议的(2PC)

两阶段提交:prepare,commit
prepare:预处理阶段
commit:提交/回滚阶段

AT模式

是一种无侵入的分布式事务解决方案,也是二阶段提交的。
第一阶段:seata会去拦截sql语句,会先去查询这条sql要操作的数据,保存成before image,执行sql,将更新后的数据保存为after image,给这条数据生成行锁。
第二阶段提交:删除掉保存的数据快照(before/after image)和行锁。
第二阶段回滚:先校验是否有脏写,即对比数据库的数据和after image中的是否一致,如果有脏写,需要人工处理;如果没有脏写,使用after image还原数据。

TCC模式

需要使用者在自己的业务代码中实现Try(事务发起),Confirm(提交),Cancel(回滚)操作。
和AT模式对比:

  • 侵入性比较强
  • 性能更好,因为整个过程中,基本没有使用锁。
  • 更灵活

seata架构中的三大角色:

  • TC:事务协调者,维护全局和分支事务的状态,驱动全局事务提交或回滚
  • TM:事务管理器,定义全局事务的范围,开始,提交,回滚全局事务
  • RM:资源管理器,管理分支事务处理的资源,与TC交谈以注册分支事务和报告分支事务的状态,并驱动分支事务提交或回滚

seata的工作原理

  1. TM请求TC开启全局事务,TC生成一个XID,会在微服务的调用链中传播,保证多个微服务的子事务关联在一起
  2. RM请求TC将本地事务注册为全局事务的分支事务,通过XID关联
  3. TM请求TC告诉关于XID对应的全局事务是提交还是回滚
  4. TC驱动RRM将XID对应的本地事务进行提交或回滚

TC一般会作为一个独立的服务部署。
TM和RM是在业务代码(客户端)中使用注解,seata会自动的去维护。

seata的使用

db+nacos的方式部署高可用集群模式

seata服务端(TC)的搭建

下载seata的服务端:seata官网下载地址
我下载的是Windows版本的1.3.0
在这里插入图片描述

下载解压之后,还需要进行相关的配置
seata端存储模式有三种:

  • file(默认模式),单机模式,全局事务会话信息内存中读写并持久化本地文件root.data,性能高
  • db,高可用模式,全局事务会话信息通过db共享,性能较差
  • redis,性能高,事务信息有丢失风险
修改seata service的存储模式为db

在这里插入图片描述

修改file.conf文件

mode = "file"修改成mode = “db”
修改mysql的配置信息
在这里插入图片描述

在mysql数据库中创建相关的表
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(96),
    `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;

在这里插入图片描述

设置nacos注册中心

在这里插入图片描述

修改registry.conf文件

把registr中的type = "file" 修改为type = "nacos"
修改nacos的相关配置
`在这里插入图片描述

设置nacos配置中心

也是修改registry.conf文件
把config中的type = "file" 修改为type = "nacos"
修改nacos作为配置中心的相关配置
在这里插入图片描述

下载源码

可以在github官网中下载这个源码。里面有默认的配置信息。

在这里插入图片描述

把上图中的script文件复制一份放到seata文件夹(之前下载的seata service)中
在这里插入图片描述

修改config.txt

修改script中的config.txt,把store.mode=file改成store.mode=db
在这里插入图片描述

删除掉红框中的内容
在这里插入图片描述

修改数据库的配置信息
在这里插入图片描述

运行nacos-config.sh脚本

运行脚本,可以把config.txt里面的默认内容注册到nacos配置中心中去了。
在这里插入图片描述

服务中整合seata

pom文件中添加依赖
       <!--seata的依赖-->
        <dependency>
            <groupId>com.alibaba.cloud</groupId>
            <artifactId>spring-cloud-starter-alibaba-seata</artifactId>
        </dependency>
在微服务的数据库中新增一个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,
  PRIMARY KEY (`id`),
  UNIQUE KEY `ux_undo_log` (`xid`,`branch_id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
修改application.yml配置文件

给当前服务配置访问seata service(TC)

seata:
  registry:
    # 配置seata的注册中心
    type: nacos
    nacos:
      server-addr: 127.0.0.1:8848  
      application: seata-server              
  config:
   # 配置seata的配置中心
    type: nacos
    nacos:
      server-addr: 127.0.0.1:8848

修改启动类

添加@EnableTransactionManagement 注解和@EnableGlobalTransaction注解

@SpringBootApplication
@EnableTransactionManagement 
@EnableGlobalTransaction    
@EnableFeignClients
public class OrderApplication {
    public static void main(String[] args) {
        SpringApplication.run(OrderApplication.class,args);
    }
}
业务代码添加@GlobalTransaction注解

只需要在要使用分布式事务的方法上添加@GlobalTransaction注解
即可使用。

    @GlobalTransactional
    public Order create(Order order) {
        orderMapper.insert(order);
        stockService.reduct(order.getProductId());
        int a=1/0;
        return order;
    }

seata主要是环境的配置很负载,使用的话只需要添加注解即可

  • 14
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值