Seata分布式事务基本概念+下载安装

99 阅读3分钟

本文已参与「新人创作礼」活动,一起开启掘金创作之路。

每个微服务都调用不同的数据库,服务内部的事务由本地事务所保证,全局事务的一致性问题就没法保证。一次业务操作需要跨多个数据源或需要跨多个系统进行远程调用,就会产生分布式事务问题。

@Transaction为本地事务,@GlobalTransaction为全局事务

通用解决方案

  • 2PC(二阶段提交)
    • 是一种强一致性设计
    • 指的是准备和提交两个阶段
    • 是同步阻塞,总体而言效率低,并且存在单点故障问题,在极端条件下存在数据不一致的风险 在这里插入图片描述
  • 3PC(三阶段提交)
    • 准备阶段、预提交阶段和提交阶段
    • 引入了超时机制
    • 多引入一个阶段也多一个交互,因此性能会差一些 在这里插入图片描述
  • TCC(Try - Confirm - Cancel)
    • 2PC 和 3PC 都是数据库层面的, TCC 是业务层面的
    • TCC 对业务的侵入较大和业务紧耦合 在这里插入图片描述
  • 消息事务(RocketMQ )
    1. 先给 Broker 发送事务消息,这个消息对消费者来说不可见,然后发送成功后发送方再执行本地事务
    2. 根据本地事务的结果向 Broker 发送 Commit 或者 RollBack 命令
    3. 送方会提供一个反查事务状态接口,如果一段时间内半消息没有收到任何操作请求,那么 Broker 会通过反查接口得知发送方事务是否执行成功,然后执行 Commit 或者 RollBack 命令 在这里插入图片描述

——概念

ID+三组件模型

  • Transaction ID XID:全局事务的唯一ID
  • Transaction Coordinator(TC):事务协调器,维护全局事务的运行状态,负责协调并驱动全局事务的提交或回滚;
  • Transaction Manager(TM): 控制全局事务的边界,负责开启一个全局事务,并最终发起全局提交或全局回滚的决议;
  • Resource Manager(RM):控制分支事务,负责分支注册,状态汇报,并接收事务协调器的指令,驱动分支(本地)事务的提交和回滚; 在这里插入图片描述

分布式事务的执行流程

  1. TM开启分布式事务(TM向TC注册全局事务记录)
  2. 换业务场景,编排数据库,服务等事务内资源(RM向TC汇报准备状态)
  3. TM结束分布式事务,事务一阶段结束(TM通知TC提交 、回滚分布式事务)
  4. TC汇总事务信息,决定分布式事务是提交还是回滚
  5. TC通知所有RM提交、回滚,事务二阶段结束

AT模式的业务无侵入

  • 一阶段 在这里插入图片描述 在这里插入图片描述
  • 二阶段提交 在这里插入图片描述
  • 二阶段回滚 在这里插入图片描述在这里插入图片描述

——下载安装

  • 下载地址:seata.io/zh-cn/blog/…,选择合适的版本binary
  • 修改conf / file.conf文件:
    • 备份
    • 自定义事务组名称: vgroup_mapping.my_test_tx_group = "test_tx_group"
    • 事务日志存储模式为db: mode = "db"
    • 数据库连接信息:url = "jdbc:mysql://127.0.0.1:3306/seata" user = "root" password = "123456"
  • 在mysql建seata库
  • 在seata库里建表:
-- the table to store GlobalSession data
drop table if exists `global_table`;
create table `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`)
);

-- the table to store BranchSession data
drop table if exists `branch_table`;
create table `branch_table` (
  `branch_id` bigint not null,
  `xid` varchar(128) not null,
  `transaction_id` bigint ,
  `resource_group_id` varchar(32),
  `resource_id` varchar(256) ,
  `lock_key` varchar(128) ,
  `branch_type` varchar(8) ,
  `status` tinyint,
  `client_id` varchar(64),
  `application_data` varchar(2000),
  `gmt_create` datetime,
  `gmt_modified` datetime,
  primary key (`branch_id`),
  key `idx_xid` (`xid`)
);

-- the table to store lock data
drop table if exists `lock_table`;
create table `lock_table` (
  `row_key` varchar(128) not null,
  `xid` varchar(96),
  `transaction_id` long ,
  `branch_id` long,
  `resource_id` varchar(256) ,
  `table_name` varchar(32) ,
  `pk` varchar(36) ,
  `gmt_create` datetime ,
  `gmt_modified` datetime,
  primary key(`row_key`)
);
  • 修改conf / registry.conf配置文件
registry {
  # file 、nacos 、eureka、redis、zk、consul、etcd3、sofa
  type = "nacos"
  
  nacos {
    serverAddr = "localhost:8848"
    namespace = ""
    cluster = "default"
  }
  • 启动nacos
  • 再启动seata