热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

Seata原理!

Seata和LCN的区别1.基本实现思路是一样的,唯一区别在于回滚方式,LCN采用代理数据源假关闭连接,暂时不提交本地事务(不提交也不回滚),但是容易造成死锁。--假关闭其实就是a

Seata和LCN的区别

1. 基本实现思路是一样的,唯一区别在于回滚方式,LCN采用代理数据源假关闭连接,暂时不提交本地事务(不提交也不回滚),但是容易造成死锁。

   -- 假关闭其实就是api,因为连接也是可以被aop代理的,原生的commit被拦截到就不会走commit会进行wait线程等待,等待全局事务协调者发送通知是提交还是回滚。

2. seata采用undo_log的形式逆向生成sql语句实现回滚。

lcn存在问题:容易死锁。

例如:事务协调者宕机,无法通知参与方是提交还是回滚,所以线程会一直被占用(死锁)。

undo_log日志逆向回滚

伪代码:


1 @RequestMapping("/insertUser")
2 @GlobalTransactional
3 public String insertUser(){
4 // 第一步.添加姓名到user表;
5 int i = userMapper.insertName(“王明”);

7 // 第二步.调用会员服务修改姓名为王敏;
8 int result = rpcUrl.putName("王敏");
9
10 // 模拟报错
11 int a = 1 / 0;
12 }

使用@GlobalTransactional注解开启事务,

执行完第5行后数据就会提交到user表;

第8行会员服务同样会落实到数据库;

执行到第11行报错后会通过undo_log表逆向回滚数据;

 - undo_log表中的rollback_info字段以二进制方式记录着新增的语句,通过该字段进行逆向回滚。

Seata原理分析

  1. 发起方TM会向我们的TC协调者申请一个全局的事务id,保存到threadlocal中;
  2. TM和RM都会被Seata代理数据源,在原生的sql之前和之后保存日志到undo_log表中,方便后期实现回滚;
  3. TM从请求头中传递该全局的事务id给RM,RM从请求中头中获取到该全局事务id,并且注册该分支。
  4. 如果TM调用接口成功之后,如果报错的情况下则通知给协调者,协调者在告诉所有的分支都开始回滚,直接根据本地事务id+xid查询undo_log表 ,逆向生成sql语句回滚,同时删除该undo_log日志。
  5. 如果TM调用接口成功之后,如果没有报错的情况下则通知给协调者,协调者在告诉所有的分支都开始提交事务,直接根据本地事务id+xid删除对应的undo_log表记录即可。

笔记!

Seata实现原理

1.TM(发起方)连接到我们的TC事务协调者,创建一个全局的事务的xid,保存到ThreadLoacl中;

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

前置镜像和后置镜像sql演示:

select * from orderId=1    得到state=0 ----前置镜像

update order set state(1) where orderId=1    原生sql语句

select * from orderId=1    得到state=1 ----后置镜像

回滚(记录到undo_log):

Update order set state(0) where orderId=1  ---还原

 


推荐阅读
  • 本文探讨了如何在PHP与MySQL环境中实现高效的分页查询,包括基本的分页实现、性能优化技巧以及高级的分页策略。 ... [详细]
  • 本文详细介绍了Oracle 11g中的创建表空间的方法,以及如何设置客户端和服务端的基本配置,包括用户管理、环境变量配置等。 ... [详细]
  • Maven + Spring + MyBatis + MySQL 环境搭建与实例解析
    本文详细介绍如何使用MySQL数据库进行环境搭建,包括创建数据库表并插入示例数据。随后,逐步指导如何配置Maven项目,整合Spring框架与MyBatis,实现高效的数据访问。 ... [详细]
  • mysql数据库json类型数据,sql server json数据类型
    mysql数据库json类型数据,sql server json数据类型 ... [详细]
  • spring(22)JdbcTemplate
    2019独角兽企业重金招聘Python工程师标准###1.导入jar包,必须jar包:c3p0、mysql-connector、beans、con ... [详细]
  • 本文将详细介绍 SQL 中的 SUM 函数及其用法,并通过具体示例展示如何在实际场景中应用。 ... [详细]
  • JUnit下的测试和suite
    nsitionalENhttp:www.w3.orgTRxhtml1DTDxhtml1-transitional.dtd ... [详细]
  • 本文详细介绍了JQuery Mobile框架中特有的事件和方法,帮助开发者更好地理解和应用这些特性,提升移动Web开发的效率。 ... [详细]
  • 如何将955万数据表的17秒SQL查询优化至300毫秒
    本文详细介绍了通过优化SQL查询策略,成功将一张包含955万条记录的财务流水表的查询时间从17秒缩短至300毫秒的方法。文章不仅提供了具体的SQL优化技巧,还深入探讨了背后的数据库原理。 ... [详细]
  • 本文详细介绍了PostgreSQL与MySQL在SQL语法上的主要区别,包括如何使用COALESCE替代IFNULL、金额格式化的方法、别名处理以及日期处理等关键点。 ... [详细]
  • HTML:  将文件拖拽到此区域 ... [详细]
  • 在处理大数据量的SQL分页查询时,通常需要执行两次查询来分别获取数据和总记录数。本文介绍了一种优化方法,通过单次查询同时返回分页数据和总记录数,从而提高查询效率。 ... [详细]
  • mysql 授权!!
    为什么80%的码农都做不了架构师?MySQL的权限系统围绕着两个概念:认证-确定用户是否允许连接数据库服务器授权-确定用户是否拥有足够的权限执 ... [详细]
  • 本文介绍如何通过参数化查询来防止SQL注入攻击,确保数据库的安全性。示例代码展示了在C#中使用参数化查询添加学生信息的方法。 ... [详细]
  • CoreData 表关联详解
    在企业中,通常会有多个部门,每个员工隶属于某个部门。这种情况下,员工表和部门表之间就会形成关联关系。本文将详细介绍如何在CoreData中实现表关联,并通过示例代码展示如何添加和查询关联数据。 ... [详细]
author-avatar
卟抛棄D
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有