您的位置:

Seata分布式事务框架原理详解

一、Seata原理详解

Seata 是一个高性能、易用的分布式事务解决方案,提供了 AT/ TCC/ Saga 三种分布式事务模式,并支持 Spring、Dubbo 以及 Node.js 等多种技术栈。它提供了全局唯一的事务 ID,以及基于本地多阶段提交协议、全局锁的机制来实现分布式事务的一致性。

Seata 的整体分为 TC、RM、TM 三个部分:

TC(Transaction Coordinator): 全局事务协调者,负责全局事务的创建、提交和回滚等。在整个分布式事务中起到重要的协调作用,确保全局事务的一致性和可靠性。

TM(Transaction Manager): 事务管理器,负责本地事务的操作,包括本地事务的创建、提交和回滚等。与 TC 配合工作,实现分布式事务的管理。

RM(Resource Manager):资源管理器,负责本地资源的管理,在 Seata 中就是数据库。RM 因为修改了数据,也要保证分布式事务的一致性。

二、Seata原理是谁

Seata分布式事务框架是阿里巴巴集团于2019年推出的一个开源分布式事务框架,由鸟哥(余国跃)带领的阿里云中间件事业部孵化开发。鸟哥是阿里云中间件事业部资深技术专家,涉及阿里云分布式存储、消息队列、分布式事务等多个领域。

三、Seata原理案例

下面是 Seata 官方提供的一个订单表与库存表的分布式事务案例:


// 订单服务接口
public interface OrderService {
    public boolean createOrder(Order order);
}

// 订单表
create table order(
    id int auto_increment primary key,
    user_id int not null,
    product_id int not null,
    product_count int not null,
    add_time datetime not null,
    update_time datetime not null
);

// 库存服务接口
public interface ProductService {
    public boolean reduceStock(Product product);
}

// 库存表
create table product(
    id int auto_increment primary key,
    product_id int not null,
    stock_count int not null,
    add_time datetime not null,
    update_time datetime not null
);

在这个分布式事务案例中,订单服务需要调用库存服务,当订单服务创建订单成功后,需要更新库存表,减少对应商品的库存。这个过程中,如果有任何一个服务出现异常,就需要回滚之前的所有操作,保证数据的一致性。

四、Seata原理TCC和AT

Seata 支持 AT 和 TCC 两种分布式事务模式。

1. Seata TCC 模式

Seata TCC(Try-Confirm-Cancel)模式,一般用于业务流程比较复杂、需要参与者自己编写业务逻辑的场景。在 TCC 中,参与者需要自己实现 Try、Confirm、Cancel 三个阶段的业务逻辑。

Try 阶段通常是在主业务中创建一个唯一标示的分布式事务,并记录 TCC 方法的执行顺序与回滚操作信息;Confirm 阶段通常是在主业务提交成功后执行,以确认各参与者执行结果,如果出现异常则需要回滚操作;Cancel 阶段通常是在超时、或回滚业务后执行,以释放资源和锁。

2. Seata AT 模式

Seata AT(Automatic Transaction)模式,又称作 XA 模式,与 TCC 模式相比,AT 更加简单,不需要程序员手动实现 Try、Confirm、Cancel 三个阶段的业务逻辑。AT 模式采用了全局公共锁来保证各分支事务的一致性和可靠性。

五、Seata AT原理

Seata AT 模式,是采用了 XA (eXtended Architecture)的技术实现的分布式事务。

XA 是一个分布式事务协议和接口规范,在 Seata 中,XA 起到了很重要的作用,是实现分布式事务的关键之一。在 XA 协议下,分布式事务的流程如下:

1. TM(Transaction Manager)创建一个全局唯一的事务 ID,先后通知各个 RM 开启本地事务;

2. TM 开始全局事务,各 RM 结束本地事务;

3. 各 RM 向 TM 报告本地事务的状态,TM 根据各 RM 报告的状态,进行全局事务的提交或回滚。

六、阿里巴巴Seata原理

阿里巴巴 Seata 原理是基于全局唯一的事务 ID 来解决分布式事务一致性和可靠性的。在 Seata 中,TC 为全局唯一的事务 ID 生成器,向 TM 发送分配事务 ID 请求。TM 创建具有全局事务 ID 的本地事务,对 RM 发起分支事务请求,每个 RM 按照分支事务请求创建本地事务,最后,TM 收到 RM 的反馈后,对分布式事务进行提交或回滚操作。

七、Seata框架

Seata 框架整体上是由 TC(Transaction Coordinator)、RM(Resource Manager)、TM(Transaction Manager)和 MSE(Message Sender)四个模块组成的分布式事务解决方案。在 Seata 中,使用 Java 语言来实现整个分布式事务框架。

八、Seata分布式

Seata 分布式主要是通过对事务进行全局的管理和控制,来确保分布式事务的一致性和可靠性。在分布式应用场景中,不同的节点可能位于不同的地方,而这些节点之前可能会有通信延迟、不可靠的网络等问题。Seata 分布式主要考虑了这些因素,引入了 Heartbeat 等技术来处理节点通信延迟或故障的问题。

九、Seata 三大模式

1. Seata AT 模式

Seata AT 模式采用了 XA 协议,在分布式事务过程中,Seata AT 通过事务管理器来实现全局事务的管理和控制,从而确保分布式事务的一致性和可靠性。在 AT 模式中,使用全局公共锁来防止数据被多方操作问题。

2. Seata TCC 模式

Seata TCC 是一种分布式事务模式,相对于 AT 模式,TCC 模式具有更高的可扩展性。与AT模式不同的是,TCC模式下,业务逻辑中 Try、Confirm、Cancel 操作需要业务开发人员自行实现。Try 阶段一般用来预留业务数据,Confirm 阶段一般用来确认业务数据,而 Cancel 阶段一般用来释放业务资源。

3. Seata SAGA 模式

Seata Saga 模式是一种基于自动补偿机制的分布式事务模式。在 Saga 模式下,Seata 主要通过对事务进行状态记录,来确保分布式事务的一致性和可靠性。在分布式事务过程中,当一个事务执行失败时,Seata 就会自动回滚该事务。

十、Seata的几种模式选取

在使用 Seata 的过程中,开发人员可以根据实际需求,选择不同的分布式事务模式来实现分布式事务的控制和管理。对于事务较为简单的情况,可以选择 Seata AT 模式来处理;对于事务较为复杂的情况,可以选择 Seata TCC 或 Saga 模式来处理。

代码示例

1. Seata AT 模式示例

在 Seata AT 模式下,可以通过在 Spring Boot 项目中添加 seata-spring-boot-starter 依赖,来实现分布式事务的控制和管理。

添加依赖

<dependency>
    <groupId>io.seata</groupId>
    <artifactId>seata-all</artifactId>
    <version>1.4.0</version>
</dependency>
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-seata</artifactId>
    <version>2.2.1.RELEASE</version>
</dependency>
配置文件

# DataSource
spring.datasource.url = jdbc:mysql://localhost:3306/test
spring.datasource.username = root
spring.datasource.password = 123456
spring.datasource.driver-class-name = com.mysql.jdbc.Driver
spring.datasource.type = com.alibaba.druid.pool.DruidDataSource

# SEATA
spring.cloud.alibaba.seata.tx-service-group = seata-tx-group
feign.hystrix.enabled = false

# MyBatis
mybatis.mapper-locations = classpath:mapper/*.xml

mybatis.configuration.map-underscore-to-camel-case=true
mybatis.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl

# Spring
spring.application.name=springcloud-storage-service
server.port=8081
eureka.instance.instance-id=${spring.application.name}:${spring.cloud.client.ip-address}:${server.port}
eureka.client.service-url.defaultZone=http://localhost:8761/eureka/
分布式事务管理器

@Data
@Configuration
public class DataSourceProxyConfig {

    @Autowired
    private DataSourceProperties dataSourceProperties;

    @Bean
    public DataSource dataSource() {

        DruidDataSource datasource = new DruidDataSource();
        datasource.setUrl(dataSourceProperties.getUrl());
        datasource.setUsername(dataSourceProperties.getUsername());
        datasource.setPassword(dataSourceProperties.getPassword());
        datasource.setDriverClassName(dataSourceProperties.getDriverClassName());

        // spring datasource 监控配置
        datasource.setFilters("stat,wall,log4j");
        datasource.setMaxActive(20);
        datasource.setInitialSize(1);
        datasource.setMaxWait(60000);
        datasource.setMinIdle(1);
        datasource.setValidationQuery("select 'x'");
        datasource.setTestOnBorrow(false);
        datasource.setTestOnReturn(false);
        datasource.setTestWhileIdle(true);
        datasource.setTimeBetweenEvictionRunsMillis(60000);
        datasource.setMinEvictableIdleTimeMillis(25200000);

        try {
            datasource.setFilters("stat");
        } catch (SQLException e) {
            e.printStackTrace();
        }

        return new DataSourceProxy(datasource);
    }
}

2. Seata TCC 模式示例

在 Seata TCC 模式下,需要在业务逻辑中实现 Try、Confirm、Cancel 三个阶段的业务逻辑。

接口定义