分布式事务-seata原理和源码解析

实现原理

  1. TM(发起方)会向我们的TC协调者申请一个全局的事务id,保存到threadlocal中;
  2. TM(发起方)和RM(参与方)都被Seata的数据数据源实现代理,在原生的sql之前和之后保存原来和修改后日志到undo_log中,方便后期实现回滚。
  3. TM(发起方)使feign客户端调用接口时候,在ThreadLoacl中获取xid,设置到请求头中;
  4. RM(参与方)从请求中获取到该xid,设置到ThreadLoacl中,同时也会向seataserver注册该分支事务。
  5. TM(发起方)将当前本地事务的结果,告诉给协调者TC,协调者TC在通知所有的分支是否回滚。
  6. TM(发起方)如果调用接口成功之后抛出异常的情况下,告诉给协调者TC,协调者TC在通知所有的分支根据根据全局的xid和分支事务的id 查询分支数据源的undo_log日志表逆向生成sql语句实现回滚,同时删除对应的undo_log日志
  7. TM(发起方)如果调用接口成功之后没有抛出任何的异常,告诉给协调者TC,协调者TC在通知所有的分支根据根据全局的xid和分支事务的id 查询分支数据源的 删除对应的undo_log日志表

前置镜像:(数据之前的样子【备份】)
后置镜像:(数据之后的样子【备份】)

如何逆向实现sql语句:
insert 逆向 delete
delete 逆向 insert
update 逆向 update

Seata与LCN的区别?

  1. 基本实现的思路是一样的,唯一区别在于回滚的方式 LCN采用代理数据源假关闭连接,暂时不提交本地事务,但是容易造成数据的死锁。
  2. Seata采用undo_log的形式逆向生成sql语句实现回滚,避免死锁现象但是容易出现脏读。

源码分析

AOP入口类分析

  1. 项目中会引入到SpringCloud-Alibaba-seata. jar执行spring. factories 配置中读取 Globa ITransactionAutoConfiguration 配置类,会加载到GlobaITransactionScanner 到Spring的容器中。
  2. G loba ITransact i onScanner实现了AbstractAutoProxyCreator、InitializingBean 接口。
    Abstr actAutoProxyCreator: SpringAOP原生类创建代理对象。
    InitializingBean:SpringBena生命周期初始化
    GlobalTransactionScanner:对象初始化成功之后开始注册我们的 tm和 tc 到全局协调者中去。
    在这里插入图片描述

AbstractAutoProxyCreator 回调的方法 wrapIfNecessary 创建我们的 GlobaITransactionalInterceptor.
在这里插入图片描述
执行发起方方法前会执行我们的 GlobaITransactionalInterceptor 的 invoke 方法,判断有没有加上全局事务注解,再执行我们的transactionaITemplate的execute 方法,

在这里插入图片描述

在这里插入图片描述

处理分布式事务的核心方法:
在这里插入图片描述

发起方在方法上面加上@GlobaITransactional,会被aop拦截.

创建全局事务id(xid)

开启事务方法
在这里插入图片描述

发送请求给TC创建xid
在这里插入图片描述
在这里插入图片描述

前置镜像和后置镜像

查找对于源码的方法,可以将数据库中的UNDO_LOG表删除,根据报错信息查找。
在这里插入图片描述

在这里插入图片描述

存入UNDO_LOG表数据
在这里插入图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值