关于Seata基本使用及二阶提交流程

 更新时间:2025年04月02日 10:30:28   作者:Xwzzz_  
这篇文章主要介绍了关于Seata基本使用及二阶提交流程,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教

一,Seata 的基本使用

环境搭建

  • 下载 Seata:可以从 Seata 官网 或者 GitHub 上获取最新版本。
  • 启动 Seata Server:下载 Seata 后,配置并启动 Seata Server,Seata 提供了一个默认的 Nacos 配置中心,也可以使用其他配置中心。

引入依赖

  • 在微服务应用中,可以通过 Maven 或 Gradle 引入 Seata 的相关依赖。
<dependency>
    <groupId>io.seata</groupId>
    <artifactId>seata-spring-boot-starter</artifactId>
    <version>1.6.1</version> <!-- 根据需要选择最新版本 -->
</dependency>

配置 Seata

  • 在使用全局事务之前,需要确保 Seata Server 已经启动,并且应用程序的 application.yml 配置正确
seata:
  tx-service-group: my_test_tx_group  # 事务分组
  service:
    vgroup-mapping:
      my_test_tx_group: default
    enable-auto-data-source-proxy: true  # 自动代理数据源
  registry:
    type: nacos  # 注册中心类型
    nacos:
      server-addr: 127.0.0.1:8848  # Nacos 地址
      namespace: public
      group: SEATA_GROUP
  config:
    type: nacos
    nacos:
      server-addr: 127.0.0.1:8848
      namespace: public
      group: SEATA_GROUP

在全局事务中使用 @GlobalTransactional

  • 全局事务的控制需要在方法上添加 @GlobalTransactional,以确保该方法及其调用的所有子事务受 Seata 统一管理。
import io.seata.spring.annotation.GlobalTransactional;
import org.springframework.stereotype.Service;
import org.springframework.beans.factory.annotation.Autowired;

@Service
public class OrderService {

    @Autowired
    private StockService stockService;

    @Autowired
    private PaymentService paymentService;

    @GlobalTransactional(name = "order-create", rollbackFor = Exception.class)
    public void createOrder(String userId, String productId, int amount) {
        // 扣减库存
        stockService.deductStock(productId, amount);

        // 处理支付
        paymentService.processPayment(userId, amount);

        // 插入订单记录
        System.out.println("订单创建成功!");
    }
}

在分支事务中使用 @Transactional

  • Seata 在全局事务中,所有数据库操作会自动成为分支事务。
  • StockService 中:
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service
public class StockService {

    @Transactional
    public void deductStock(String productId, int amount) {
        // 执行数据库库存扣减操作
        System.out.println("库存扣减成功!");
    }
}

虽然 StockService 仍然使用的是本地事务 @Transactional,但因@GlobalTransactional 处于全局事务上下文中,Seata 会自动代理并管理它的事务

二,Seata 的工作原理

Seata 通过引入 全局事务管理分支事务 来解决分布式系统中的事务一致性问题。

它使用类似于传统数据库事务中的 二阶段提交(2PC,Two-Phase Commit) 协议来确保事务的原子性。

二阶段提交(2PC)过程

Seata 采用二阶段提交协议(2PC)来确保分布式事务的一致性。以下是二阶段提交的详细流程:

1. 第一阶段:事务预备(Try阶段)

  • 全局事务开始:客户端应用向 Seata Server 发起请求,Seata 会生成一个全局事务 ID(XID),并返回给客户端应用。全局事务标识用于追踪整个分布式事务。
// 启动全局事务
GlobalTransaction tx = GlobalTransactionContext.getCurrentOrCreate();
tx.begin();
  • 分支事务注册:每个参与者(微服务)启动后,会向 Seata Server 注册自己作为一个分支事务,Seata Server 会为每个分支事务分配一个唯一的事务分支 ID(Branch ID)。
  • Try 阶段:每个微服务会执行 Try 操作,即准备执行本地事务操作,但不提交数据。例如,更新某个数据库中的记录,但不提交。
  • 执行数据库操作:每个参与的子事务都会执行数据库更新,但不会真正提交,而是进入 prepare 状态(对于 AT 模式,这意味着生成 undo_log)。

2. 第二阶段:提交(Commit)或回滚(Rollback)

提交(Commit)

  • Seata Server 收到全局事务提交请求后,通知所有分支事务提交事务。
  • 分支事务提交数据库操作(删除 undo_log)。

回滚(Rollback)

  • 如果 Seata Server 发现某个分支事务执行失败,则通知所有已提交的分支事务回滚,恢复 undo_log 记录的数据。

三,Seata 的四种事务模式

1. AT 模式(自动事务模式)

AT(Auto Transaction)模式是 Seata 中最常用的分布式事务模式,适用于对数据库执行常规的 CRUD(增、删、改、查)操作的场景,尤其是简单的 SQL 操作。

特点

  • 自动化:AT 模式在数据库的每个操作上都自动代理,开发者无需显式地编写事务的提交和回滚操作。Seata 会自动插入 undo 日志,在事务回滚时自动恢复数据库的原始状态。
  • 无须业务代码改动:AT 模式的关键优势是,开发者无需修改现有的业务代码。通过 Seata 自动管理事务,开发者只需确保数据库支持 undo 日志(例如 MySQL、Oracle 等)。
  • 仅适用于数据库操作:AT 模式适用于标准的数据库操作,它依赖于数据库的日志和 undo 日志机制。

工作原理

  • Try 阶段:Seata 会拦截数据库的更新操作,并记录 undo 日志,但不立即提交。此时,数据库的数据并未真正修改,而是保留了“回滚”的信息。
  • Commit 阶段:当全局事务提交时,Seata 会通过协调所有分支事务,最终确认提交所有的数据修改。
  • Rollback 阶段:如果全局事务失败,则会通过回滚所有分支事务的操作,恢复数据。

适用场景

  • 适用于大多数微服务场景,尤其是直接依赖数据库操作的业务逻辑,Seata 会自动进行事务控制。

2. TCC 模式(Try-Confirm-Cancel)

TCC(Try-Confirm-Cancel)模式是一种基于补偿的分布式事务模式,它适用于业务操作较为复杂、涉及多个服务的场景。与 AT 模式的自动提交和回滚不同,TCC 模式要求开发者显式地实现 TryConfirmCancel 这三个阶段。

特点

  • 精确控制:开发者需要编写 Try、Confirm 和 Cancel 方法,能够精确控制每个阶段的事务操作。
  • 高灵活性:TCC 模式适用于复杂的业务操作,尤其是那些需要进行资源锁定、状态更新、外部系统调用的场景。
  • 手动补偿:TCC 模式的关键是补偿机制,若某个操作失败,需要通过 Cancel 操作来撤销之前的资源占用或状态变更。

工作原理

  • Try 阶段:执行实际的业务操作,但不会提交(例如,锁定资源、预扣资金)。此时,操作是幂等的,并且不改变系统状态。
  • Confirm 阶段:如果 Try 阶段成功,Confirm 阶段会提交操作,确认业务操作完成(例如,实际扣款、最终更新库存)。
  • Cancel 阶段:如果 Try 阶段失败或某个分支事务失败,则执行 Cancel 操作,撤销之前的操作(例如,解锁资源、退款)。

适用场景

  • 长时间执行的业务:例如支付、库存扣减等复杂的跨服务操作,需要实现显式的补偿机制。
  • 必须确保操作的最终一致性:TCC 能够处理在服务之间的协作,并确保每个服务能明确知道何时提交或回滚事务。

3. SAGA 模式

SAGA(长事务模式)是一个分布式事务处理模式,适用于跨多个微服务的长事务。与 TCC 模式不同,SAGA 模式通过将长事务拆分成多个小事务来保证一致性,每个小事务都会有一个补偿事务(Compensating Transaction),用于回滚操作。

特点

  • 长事务拆分:将大事务拆分为一系列小事务,每个小事务都可以独立提交或回滚。
  • 补偿机制:每个小事务都需要实现一个补偿事务,当某个事务失败时,通过补偿事务来撤销之前的操作。
  • 可以异步执行:每个子事务之间可以独立执行,并且可以异步执行,不需要像 TCC 那样锁定资源。

工作原理

  • 子事务:将全局事务拆分为多个子事务,每个子事务执行独立的操作(例如,支付、库存扣减等)。
  • 补偿操作:每个子事务都有相应的补偿操作。如果某个子事务失败,执行补偿操作撤销之前的操作。
  • 全局事务结束:当所有子事务都执行成功时,结束整个 SAGA 事务;如果某个子事务失败,则根据补偿规则进行回滚。

适用场景

  • 长时间的、跨多个服务的事务:例如订单的创建、支付、发货等操作。
  • 能够容忍部分失败的场景:SAGA 模式适用于业务流程中的某些操作失败后,可以通过补偿机制修复的场景。

4. XA 模式(原生分布式事务)

XA 模式是传统的分布式事务协议,它基于 XA协议,是一种强一致性的分布式事务模式。Seata 的 XA 模式要求参与者支持 XA 事务协议,例如数据库、消息队列等。

特点

  • 强一致性:XA 模式是最严格的分布式事务协议,确保所有分布式事务的最终一致性。
  • 两阶段提交协议(2PC):与 AT 模式类似,XA 模式也采用了 2PC 协议来管理事务一致性。
  • 依赖于底层数据库的支持:必须使用支持 XA 事务的数据库(例如,MySQL、Oracle 等)。

工作原理

  • 第一阶段(Prepare):所有参与者准备提交事务,但不提交。
  • 第二阶段(Commit/Rollback):如果所有参与者都准备好,则提交事务,否则回滚事务。

适用场景

  • 严格要求强一致性的场景:例如银行转账等对事务一致性要求极高的业务。

总结

Seata 支持以下四种分布式事务模式:

  1. AT 模式:适用于标准的数据库操作,自动管理事务,适合不涉及复杂业务逻辑的场景。
  2. TCC 模式:适用于跨多个服务的复杂业务,需要手动编写补偿逻辑。
  3. SAGA 模式:适用于长事务,适合拆分为多个子事务的场景,每个子事务都可以独立回滚。
  4. XA 模式:严格一致性的分布式事务协议,适用于需要强一致性的场景,如金融交易等。

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • springMVC的生命周期详解

    springMVC的生命周期详解

    本篇文章主要介绍了springMVC的生命周期详解,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-03-03
  • java爬虫之使用HttpClient模拟浏览器发送请求方法详解

    java爬虫之使用HttpClient模拟浏览器发送请求方法详解

    这篇文章主要介绍了java爬虫之使用HttpClient模拟浏览器发送请求方法详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-07-07
  • 零基础写Java知乎爬虫之抓取知乎答案

    零基础写Java知乎爬虫之抓取知乎答案

    上篇文章我们已经能把知乎的问题抓出来了,但是答案还木有抓出来。这一回合,我们就连着把答案也一起从网站中抠出来=。=
    2014-11-11
  • Java快速实现Excel表格转SVG的示例详解

    Java快速实现Excel表格转SVG的示例详解

    对于开发者来说,使用 Java 来实现 Excel 到 SVG 的转换,是一种更灵活、可控的方式,本文将演示如何通过简单的 Java 代码完成这一过程,希望对大家有所帮助
    2025-09-09
  • springboot之excel工具类使用及说明

    springboot之excel工具类使用及说明

    本文介绍了一个批量处理Excel数据的小工具,提供导入导出功能,通过定义数据类和处理函数即可实现数据处理,最后进行模拟请求和文件数据生成,以测试工具的正确性
    2026-04-04
  • springBoot 启动指定配置文件环境多种方案(最新推荐)

    springBoot 启动指定配置文件环境多种方案(最新推荐)

    springBoot 启动指定配置文件环境理论上是有多种方案的,一般都是结合我们的实际业务选择不同的方案,比如,有pom.xml文件指定、maven命令行指定、配置文件指定、启动jar包时指定等方案,今天我们一一分享一下,需要的朋友可以参考下
    2023-09-09
  • Java AtomicInteger类的使用方法详解

    Java AtomicInteger类的使用方法详解

    这篇文章主要介绍了Java AtomicInteger类的使用方法详解,文中有具体实例代码,具有一定参考价值,需要的朋友可以了解下。
    2017-10-10
  • 关于Spring组成的七大模块详解

    关于Spring组成的七大模块详解

    Spring是一个开源的应用框架,用于简化企业级应用开发,它由核心容器、应用上下文、面向切面编程、JDBC和DAO模块、对象实体映射、Web模块和MVC模块七大模块组成,这些模块提供了各种功能,如依赖注入、面向切面编程、ORM支持、Web开发等,以帮助开发者更高效地开发应用
    2025-11-11
  • Java数组的定义、初始化、及二维数组用法分析

    Java数组的定义、初始化、及二维数组用法分析

    这篇文章主要介绍了Java数组的定义、初始化、及二维数组用法,结合具体实例形式分析了java数组概念、功能、数组定义、静态数组、动态数组、二维数组等相关使用技巧,需要的朋友可以参考下
    2019-01-01
  • 如何解决struts2日期类型转换

    如何解决struts2日期类型转换

    在Struts2中,一般的内置类型都会在由系统自动进行转换.但是Date类型好像有时候行,有时候不行。比如我这次,本地运行正常,一上测试服务器就不行了。这个转换类是从网上看的:
    2013-03-03

最新评论