热门标签 | 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  ---还原

 


推荐阅读
  • 本文探讨了在 SQL Server 中使用 JDBC 插入数据时遇到的问题。通过详细分析代码和数据库配置,提供了解决方案并解释了潜在的原因。 ... [详细]
  • 本文介绍 SQL Server 的基本概念和操作,涵盖系统数据库、常用数据类型、表的创建及增删改查等基础操作。通过实例帮助读者快速上手 SQL Server 数据库管理。 ... [详细]
  • 阿里云ecs怎么配置php环境,阿里云ecs配置选择 ... [详细]
  • 本文详细介绍了优化DB2数据库性能的多种方法,涵盖统计信息更新、缓冲池调整、日志缓冲区配置、应用程序堆大小设置、排序堆参数调整、代理程序管理、锁机制优化、活动应用程序限制、页清除程序配置、I/O服务器数量设定以及编入组提交数调整等方面。通过这些技术手段,可以显著提升数据库的运行效率和响应速度。 ... [详细]
  • 本文深入探讨了SQL数据库中常见的面试问题,包括如何获取自增字段的当前值、防止SQL注入的方法、游标的作用与使用、索引的形式及其优缺点,以及事务和存储过程的概念。通过详细的解答和示例,帮助读者更好地理解和应对这些技术问题。 ... [详细]
  • 1.执行sqlsever存储过程,消息:SQLServer阻止了对组件“AdHocDistributedQueries”的STATEMENT“OpenRowsetOpenDatas ... [详细]
  • 本文详细介绍了一种通过MySQL弱口令漏洞在Windows操作系统上获取SYSTEM权限的方法。该方法涉及使用自定义UDF DLL文件来执行任意命令,从而实现对远程服务器的完全控制。 ... [详细]
  • MySQL 基础操作与优化
    本文详细介绍了 MySQL 的基础连接、数据库及表的操作,涵盖创建、修改、删除等常用命令,并深入解析了数据类型、列属性、索引、外键和存储引擎等内容。 ... [详细]
  • 深入解析ESFramework中的AgileTcp组件
    本文详细介绍了ESFramework框架中AgileTcp组件的设计与实现。AgileTcp是ESFramework提供的ITcp接口的高效实现,旨在优化TCP通信的性能和结构清晰度。 ... [详细]
  • 优化SQL Server批量数据插入存储过程的实现
    本文介绍了一种改进的SQL Server存储过程,用于生成批量插入语句。该方法不仅提高了性能,还支持单行和多行模式,适用于SQL Server 2005及以上版本。 ... [详细]
  • Kubernetes 持久化存储与数据卷详解
    本文深入探讨 Kubernetes 中持久化存储的使用场景、PV/PVC/StorageClass 的基本操作及其实现原理,旨在帮助读者理解如何高效管理容器化应用的数据持久化需求。 ... [详细]
  • 深入解析动态代理模式:23种设计模式之三
    在设计模式中,动态代理模式是应用最为广泛的一种代理模式。它允许我们在运行时动态创建代理对象,并在调用方法时进行增强处理。本文将详细介绍动态代理的实现机制及其应用场景。 ... [详细]
  • Python + Pytest 接口自动化测试中 Token 关联登录的实现方法
    本文将深入探讨 Python 和 Pytest 在接口自动化测试中如何实现 Token 关联登录,内容详尽、逻辑清晰,旨在帮助读者掌握这一关键技能。 ... [详细]
  • 本文详细介绍了MySQL数据库中的Bin Log和Redo Log,阐述了它们在日志记录机制、应用场景以及数据恢复方面的区别。通过对比分析,帮助读者更好地理解这两种日志文件的作用和特性。 ... [详细]
  • 优化Flask应用的并发处理:解决Mysql连接过多问题
    本文探讨了在Flask应用中通过优化后端架构来应对高并发请求,特别是针对Mysql 'too many connections' 错误的解决方案。我们将介绍如何利用Redis缓存、Gunicorn多进程和Celery异步任务队列来提升系统的性能和稳定性。 ... [详细]
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社区 版权所有