首页 > 其他分享 >分布式事务相关

分布式事务相关

时间:2023-04-09 17:13:07浏览次数:38  
标签:事务 name 回滚 阶段 提交 RM 相关 分布式

1.有遇到分布式事务?

在RPC远程调用过程中,A调用B服务的接口后,A接口报错,无法回滚B接口的事务,最终造成A事务回滚,B事务没有回滚。

注:在单体架构中,如果存在多数据源,每个数据源都有自己独立的事务管理器,那么这时也会存在多数据源事务管理分布式事务的问题。解决方案:jta+Atomikos

2.分布式事务解决方案?

  • 单体架构多数据源项目,采用jta+Atomikos ;
  • 采用MQ的形式解决,采用最终一致性的思想。
  • Alibaba的Seata解决,基于2PC,不适用于和外部接口保证分布式事务问题。

2PC,3PC属于业务代码无入侵方案,都是基于XA规范实现的,TCC,Sega属于业务入侵的方案,2PC,3PC设计的一些角色(XA规范的角色)组成如下:

  • AP:应用程序本身
  • RM:资源管理器,也就是事务的参与者,大部分情况下指数据库,一个分布式事务往往涉及到多个RM。
  • TM:事务管理器,负责管理全局事务,分配事务的唯一标识,负责事务的回滚,提交等。

2PC(2阶段提交)###

2pc将事务分为2各阶段:##准备阶段##和##提交阶段##

  • 准备阶段:
    1.事务管理器(TM)向所有涉及到的资源管理器(事务参与者RM)发送消息询问是否可以执行事务操作,并等待其回复。
    2.资源管理器(RM)接收到消息后,开始向执行本地数据库预操作,比如写redolog/undolog日志,此时并不会提交事务
    3.资源管理器(RM)如果事务操作执行成功,就向事务管理器(TM)回复ack标识已就绪,否则就回复ack未就绪标识。

  • 提交阶段
    提交阶段的核心是询问事务的参与者是否提交本地事务成功。
    当所有的事务参与者都是就绪状态的话:
    1.事务管理器(TM)向所有参与者发送消息,标识可以提交事务(Commit消息)
    2.资源管理器(RM)接收到消息后提交本地事务操作,执行完之后释放整个事务期间占有的资源
    3.资源管理器(RM)发送“事务已提交”的消息(ACK消息)
    4.事务管理器(TM)接收到所有事务参与者ACK消息之后,分布式事务结束。

  • 当任一事务参与者的状态是“未就绪”时:
    1.TM向所有的参与者发送回滚消息(RollBack消息)
    2.RM接收到RollBack消息之后执行本地数据库回滚操作。
    3.RM回复已回滚的ACK消息
    4.TM接受到所有的RMack消息后,中断事务。

总结:
1.准备阶段主要是测试RM能否执行本地事务(这一步并不会提交事务!!)
2.提交阶段****TM会根据准备阶段中RMACK消息来决定是执行数据的回滚还是提交操作。
3.提交阶段之后一定会结束当前的分布式事务。

2PC优点:
1.实现简单,各大主流数据库都有自己的实现。
2.针对的是数据的强一致性。

2PC缺点:
1.同步阻塞:在事务参与者提交事务之前会一直占有相关资源,其他事务要操作资源的话就会阻塞。
2.数据不一致:由于网络问题或者TM宕机或造成数据不一致的情况,如在第二阶段提交阶段时,网络问题导致部分参与者接受不到commit/rollback的话会造成数据不一致。
3.单点问题:如果TM在准备阶段完成之后挂掉了,那个参与者会一直卡在提交阶段。

3PC(3阶段提交)

3pc是在2pc的基础上做了一些优化,将2pc的准备阶段做了细分,分为准备阶段(canCommit)预提交阶段(preCommit)

  • 准备阶段(canCommit):这一步不会执行事务操作,只是像资源管理器(RM)发送准备请求,询问事务的参与者能否执行本地事务操作,RM回复y或者n或者超时。若果任一RM回复n,则中断事务操作(像所有参与者发送Abort消息),否则进入预提交阶段

  • 预提交阶段(preCommit):TM向所有的RM发送预提交请求,RM收到消息后执行本地事务操作,如写undolog/redolog操作。
    如果RM执行预提交事务成功,则返回ACK,如果任一RM返回N,则中断事务操作(向所有参与者发送Abort消息),否则进入执行事务提交阶段

  • 执行事务提交阶段(doCommit):开始执行真正的事务提交,TM向所有的RM发送事务提交请求,RM收到消息后开始正式的提交任务,并释放占用的资源。
    若任一RM没有正确的提交事务,就中断事务,TM向所有的RM发送Abort消息,RM收到消息后开始本地事务回滚。

3pc的改进:
在事务管理器和事务的参与者之间引入了超时机制,在一定时间内没有收到事务参与者的消息,就会默认失败,避免事务参与者一直阻塞占用资源,2pc中只有事务管理器才有超时机制,当事务参与者长时间与事务管理器没有通讯的情况下,就会一直阻塞无法释放资源。

TCC(try,confirm,cancel)补偿机制

TCC分为三个阶段:
1.Try尝试阶段:尝试执行,完成业务检查,并预留好业务资源。
2.Confirm确认阶段:确认执行,当所有事务参与者的try阶段都成功执行才会执行confirm,confirm阶段会处理try阶段预留的业务资源,否则就会执行cancel。
3.Cancel取消阶段:取消执行,释放try阶段预留的业务资源。

每个阶段由业务代码控制,避免长事务,性能更好。一般情况下使用TCC机制来实现时,需要我们自己来实现Try,Confirm,Cancel三个方法,来达到最终一致性。

  • Try阶段阶段如果出现问题,可以执行Cancel,如果Confirm或者Cancel阶段失败了会怎么办
    TCC会记录事务日志并持久化到某种存储介质上,如本地文件,数据库,zookeeper等,事务日志包含了事务的执行状态,如执行成功或者失败,以及在哪一步失败,如果发现是Confirm或者Cancel阶段失败的话,会进行重试,重试次数通常为6次,如果超过6次还没成功,就需要人工介入。

  • TCC和2PC/3PC的区别?
    1.TCC对代码有侵入,2PC/3PC对代码无侵入。
    2.TCC追求的是最终一致性,不会一直持有业务资源的锁,2PC/3PC追求的是强一致性,在两阶段提交的整个过程中,会一直持有数据库的锁。

Seata分布式事务解决方案:

Seata为用户提供了AT,TCC,SAGA和XA事务模式,以AT事务模式分支举例:
业务表:product:

AT分支事务逻辑:

update product set name = 'GTS' where name = 'TXC';
sql```

- 第一阶段:
1.解析sql:得到sql的类型(update),表(product),条件(name = 'TXC');
2.查询前置镜像,根据解析的信息,生成查询语句,定位数据;

select id, name, since from product where name = 'TXC';
sql```

得到的前置镜像:

3.执行业务SQL,更新记录的name为'GTS'。
4.查询后置镜像,根据前置镜像的结果,通过主键定位数据。

select id, name, since from product where id = 1;
sql```

得到后置镜像:
![](/i/l/?n=23&i=blog/2335932/202304/2335932-20230409164654337-1207712254.png)

5.插入回滚日志:将后置镜像数据以及业务信息的sql组成一条回滚日志,插入到undo_log表中。

{
"branchId": 641789253,
"undoItems": [{
"afterImage": {
"rows": [{
"fields": [{
"name": "id",
"type": 4,
"value": 1
}, {
"name": "name",
"type": 12,
"value": "GTS"
}, {
"name": "since",
"type": 12,
"value": "2014"
}]
}],
"tableName": "product"
},
"beforeImage": {
"rows": [{
"fields": [{
"name": "id",
"type": 4,
"value": 1
}, {
"name": "name",
"type": 12,
"value": "TXC"
}, {
"name": "since",
"type": 12,
"value": "2014"
}]
}],
"tableName": "product"
},
"sqlType": "UPDATE"
}],
"xid": "xid:xxx"
}
json```

6.提交前,向TC注册分支,申请product表中主键id=1的全局锁
7.本地事务提交。
8.本地事务提交结果上报给TC。

  • 两阶段-回滚
    1.收到TC的回滚请求,本地开启一个事务。
    2.通过XID和Branch ID查找相应的un_dolog记录。
    3.拿undolog中的后置镜像与当前数据比较,如果不同,说明当前数据已被修改,这种情况需要根据配置的策略来处理。
    4.根据undolog中的前置镜像和业务sql来生成回滚语句。
update product set name = 'TXC' where id = 1;

5.提交本地事务,并将回滚结果上报给TC。

标签:事务,name,回滚,阶段,提交,RM,相关,分布式
From: https://www.cnblogs.com/huang580256/p/17300585.html

相关文章

  • 分布式存储技术(下):宽表存储与全文搜索引擎的架构原理、特性、优缺点解析
    对于写密集型应用,每天写入量巨大,数据增长量无法预估,且对性能和可靠性要求非常高,普通关系型数据库无法满足其需求。对于全文搜索和数据分析这类对查询性能要求极高的场景也是如此。为了进一步满足上面两类场景的需求,有了宽表存储和搜索引擎技术,本文将对他们的架构、原理缺点做介绍。......
  • 一文讲透 Redis 事务 (事务模式 VS Lua 脚本)
    准确的讲,Redis事务包含两种模式:事务模式和Lua脚本。先说结论:Redis的事务模式具备如下特点:保证隔离性;无法保证持久性;具备了一定的原子性,但不支持回滚;一致性的概念有分歧,假设在一致性的核心是约束的语意下,Redis的事务可以保证一致性。但Lua脚本更具备实用场景,它......
  • 分布式消息系统RocketMQ
    一、RocketMQ简介ApacheRocketMQ是一个采用Java语言开发的分布式的消息系统,由阿里巴巴团队开发,与2016年底贡献给Apache,成为了Apache的一个顶级项目。在阿里内部,RocketMQ很好地服务了集团大大小小上千个应用,在每年的双十一当天,更有不可思议的万亿级消息通过RocketMQ流转(在......
  • models.ForeignKey()的一些相关参数说明
    models.ForeignKey()是DjangoORM中的一个字段类型,用于定义关联关系。在使用models.ForeignKey()时,可以传入一些参数来控制关联行为。以下是一些常用的参数说明:to:指定关联的目标模型类。on_delete:指定当关联对象被删除时的行为。CASCADE或者SET_NULLrelated_name:指定反向......
  • 记录相关操作
    目录一、介绍二、查询数据SELECT-单表查询1.查询的语法1.查询关键字之select、from2.查询关键字之where筛选3.查询关键字之groupby分组3.2聚合函数3.3group_concat()3.4having过滤4.关键字之distinct去重5.关键字之orderby排序6.关键字之limit分页7.关键字之regexp正则......
  • python相关命令
    1,查看此电脑是否安装python,进入cmd,输入python  2,查看python安装的版本,进入cmd,输入python--version  3,查看python安装的路径,进入cmd,输入py-0p ......
  • 分布式存储技术(下):宽表存储与全文搜索引擎的架构原理、特性、优缺点解析
    对于写密集型应用,每天写入量巨大,数据增长量无法预估,且对性能和可靠性要求非常高,普通关系型数据库无法满足其需求。对于全文搜索和数据分析这类对查询性能要求极高的场景也是如此。为了进一步满足上面两类场景的需求,有了宽表存储和搜索引擎技术,本文将对他们的架构、原理、优缺点做介......
  • 分布式存储技术(下):宽表存储与全文搜索引擎的架构原理、特性、优缺点解析
    对于写密集型应用,每天写入量巨大,数据增长量无法预估,且对性能和可靠性要求非常高,普通关系型数据库无法满足其需求。对于全文搜索和数据分析这类对查询性能要求极高的场景也是如此。为了进一步满足上面两类场景的需求,有了宽表存储和搜索引擎技术,本文将对他们的架构、原理、优缺点做介......
  • 表相关操作2-完整约束、表之间关系
    目录六、表完整性约束1.介绍2.unsigned、zerofill3.notnull4.default5.unique6.primarykey7.auto_increment8.foreignkey表与表之间建关系外键字段建立一对多关系级联更新,级联删除多对多的表关系一对一关系七、修改表ALTERTABLE六、表完整性约束1.介绍约束条件就是在数据......
  • Windows 短文件名相关 - IIS短文件名泄露
    今天接网安通告,说服务器有IIS短文件名泄露。可这短文件名是什么?拿完通告后回来一通查了个遍终于看明白了。先说短文件名是什么资料传说很久很久以前windows的文件名不能超过8个文件名和3个扩展名,也就是12345678.123就是最大长度了。但是到了windows95的时候,这个长度被扩展到......