分布式事务 Seata 教程 - Seata1.4.2之AT模式执行流程解析

Seata 的 AT (Automatic Transaction) 模式是 Seata 中实现分布式事务的主要方式之一。AT 模式通过自动化的机制实现了两阶段提交(2PC),使得开发人员无需关心底层的事务细节。下面我们将详细解析 Seata 1.4.2 版本中 AT 模式的执行流程。

AT 模式的执行流程

1. 事务开始

当应用程序启动一个分布式事务时,Seata 的客户端(通常是 Spring Cloud 应用)会向 Seata Server 发送请求,开始一个新的全局事务。

  • 客户端:在客户端应用中,通过注解 @GlobalTransactional 或者编程式 API 来标记需要参与全局事务的方法。
  • Seata Server:Seata Server 收到请求后,生成一个全局事务 ID (XID),并记录到全局事务表 global_table 中。
2. 分支注册
  • 客户端:客户端应用在执行本地事务的过程中,每遇到一次数据库操作,都会生成一个分支事务 ID (Branch ID),并将该分支事务注册到 Seata Server。
  • Seata Server:Seata Server 收到分支注册请求后,将分支事务的信息记录到分支事务表 branch_table 中。
3. 执行本地操作
  • 客户端:客户端继续执行本地事务中的业务逻辑,同时 Seata 会在每个 SQL 语句执行前后记录下 Undo Log(回滚日志),以便在事务回滚时能够还原数据。
  • Undo Log:Undo Log 包括两部分:Before ImageAfter Image,分别记录了数据修改前后的状态。
4. 事务提交或回滚
  • 客户端:业务逻辑执行完毕后,客户端决定提交或回滚全局事务。
  • Seata Server
    • 如果决定提交全局事务,Seata Server 会向所有注册的分支事务发送提交命令。
    • 如果决定回滚全局事务,Seata Server 会向所有注册的分支事务发送回滚命令。
5. 分支提交或回滚
  • 客户端
    • 提交:如果接收到提交命令,客户端将提交本地事务,并清理 Undo Log。
    • 回滚:如果接收到回滚命令,客户端将使用 Undo Log 来回滚本地事务。
6. 事务结束
  • Seata Server:Seata Server 根据分支事务的结果更新全局事务的状态,并最终清理相关记录。

执行流程总结

  1. 事务开始:客户端通过注解或 API 标记开始全局事务,Seata Server 生成全局事务 ID。
  2. 分支注册:客户端在执行本地事务过程中,为每个数据库操作注册分支事务。
  3. 执行本地操作:客户端执行业务逻辑,Seata 记录 Undo Log。
  4. 事务提交或回滚:客户端决定提交或回滚全局事务。
  5. 分支提交或回滚:Seata Server 向分支事务发送提交或回滚命令。
  6. 事务结束:Seata Server 更新全局事务状态,并清理记录。

关键组件和表

  • global_table:存储全局事务的状态和相关信息。
  • branch_table:存储分支事务的状态和相关信息。
  • undo_log:记录分支事务的 Undo Log,用于回滚操作。
  • lock_table:存储事务执行过程中的锁定信息,确保事务的一致性。

示例代码

下面是一个简单的示例,展示了如何在 Spring Boot 应用中使用 Seata 的 AT 模式:

@Service
public class AccountService {

    @Autowired
    private AccountRepository accountRepository;

    @GlobalTransactional
    public void transfer(String fromName, String toName, int amount) {
        // 查询转账前账户余额
        Account fromAccount = accountRepository.findByName(fromName);
        Account toAccount = accountRepository.findByName(toName);

        // 扣减转出账户余额
        fromAccount.setBalance(fromAccount.getBalance() - amount);
        accountRepository.save(fromAccount);

        // 增加转入账户余额
        toAccount.setBalance(toAccount.getBalance() + amount);
        accountRepository.save(toAccount);
    }
}

@RestController
public class AccountController {

    @Autowired
    private AccountService accountService;

    @PostMapping("/transfer")
    public String transfer(@RequestParam("from") String fromName, @RequestParam("to") String toName, @RequestParam("amount") int amount) {
        accountService.transfer(fromName, toName, amount);
        return "Transfer successful";
    }
}

在这个例子中,@GlobalTransactional 注解用于标记 transfer 方法参与全局事务。当该方法被调用时,Seata 会自动处理事务的开始、分支注册、本地操作、提交或回滚等流程。

希望这个解析对您有所帮助!如果您有任何疑问或需要进一步的解释,请随时告诉我。

  • 4
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值