从源码角度看SEATA的AT模式的实现

前言

本篇文章是我第一次输出分布式事务相关文章,只是对Seata的AT模式代码实现设计做一个概要分析,AT模式特别注意以下方面

  • 基于支持本地 ACID 事务的关系型数据库
  • Java 应用,通过 JDBC 访问数据库
  • 全局事务角色信息:GlobalTransactionRole
    • Launcher
    • Participant

整体机制

两阶段提交协议的演变:

  1. 一阶段:业务数据和回滚日志记录在同一个本地事务中提交,释放本地锁和连接资源
  2. 二阶段:
    2.1 提交异步化,非常快速地完成
    2.2 回滚通过一阶段的回滚日志进行反向补偿

简单使用

  1. 按照官方文档说明,分别启动seata-server、account、order、Storege服务
  2. 启动测试用例:DubboBusinessTester#main
    在这里插入图片描述

源码分析

@GlobalTransactional:Launcher发起全局事务

  1. @GlobalTransactional注解拦截处理:GlobalTransactionalInterceptor#handleGlobalTransaction
    在这里插入图片描述
  2. 模板方法TransactionalTemplate#execute
    2.1 模板方法流程总结:
    (1)通过@GlobalTransactional获取事务信息txInfo
    (2)获取全局事务GlobalTransaction:tx
    (3)对txInfo的传播属性做处理
    (4)发送事务开启请求到TC,返回事务ID:xid
    (5)执行业务方法
    (6)所有业务执行完后,提交事务
    在这里插入图片描述

Participant参与事务

  1. Participant是怎样参与到全局事务的?
    1.1 通过下图发现seata客户端在数据源做了一层代理,在执行jdbc方法时会被增强处理
    在这里插入图片描述
  2. 主要逻辑在ExecuteTemplate#execute
    2.1 获取全局事务ID:xid (下面会分析xid是如何传播的)
    2.2 执行本地更新操作
    2.2 通过更新操作前后表数据TableRecords生成回滚日志:SQLUndoLog
    2.3 向TC发送分支注册请求BranchRegisterRequest,返回branchId
    2.4 提交本地事务
    在这里插入图片描述
  3. 全局事务ID(xid)传播:AlibabaDubboTransactionPropagationFilter
    3.1 发起者Launcher在TC申请到xid,设置到RpcContext中
    	String xid = RootContext.getXID();
    	RpcContext.getContext().setAttachment(RootContext.KEY_XID, xid);
    
    3.2 协作者Participant从RpcContext取出全局事务ID
    	String rpcXid = rpcXid = RpcContext.getContext().getAttachment(RootContext.KEY_XID.toLowerCase());
    	if (rpcXid != null) {
    		RootContext.bind(rpcXid);
    	}
    

TC处理全局事务请求

在这里插入图片描述
在这里插入图片描述

  1. 处理版本注册请求 在这里插入图片描述
  2. 处理事务提交请求
    在这里插入图片描述
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值