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

分布式事务

时间:2023-07-10 11:46:53浏览次数:51  
标签:事务 XA 业务 回滚 消息 https 分布式

一、分布式基础

               1、分布式事务:

               2、CAP理论:

               3、BASE理论:

      使用分布式事务的原则:不用分布式事务最好。如何无法不得不用,则考虑业务出错的频率,频率低,可以走人工补偿,频率高则引入分布式事务。

      最想说的话:很多时候,没有十全十美的方案,只能理论+实际,作出权衡。

二、常见的分布式解决方案

 

分布式事务分两大类,一类是XA类型的,一类是基于消息通知的事务方案。

常见的分布式事务解决方案:

https://view.inews.qq.com/a/20221103A00TLH00

 

1、最大努力通知

2、本地消息表

3、事务消息

4、TCC

5、XA

6、AT

7、SAGA

1、最大努力通知

https://cloud.tencent.com/developer/article/1953959

https://www.cnblogs.com/blogtech/p/14513002.html

 

最大努力通知型:通常是解决跨网络、跨服务之间分布式事务的一种方式,适用于一些最终一致性时间敏感度低的业务,且被动方处理结果不影响主动方的处理结果。

使用场景:如银行通知、商户通知,对账通知等。

特点:

            不可靠消息:业务活动主动方,在完成业务处理之后,向业务活动的被动方发送消息,直到通知N次后不再通知,允许消息丢失(不可靠消息)。
            定期校对:业务活动的被动方,根据定时策略,向业务活动主动方查询(主动方提供查询接口),恢复丢失的业务消息,对账等。

实现方式:

  • 定时任务,使用定时作业轮询发起直接通知,通知数据要做持久化操作。几乎无外部依赖。
  • 定时消息队列,基于定时消息发起通知,同样需要对通知请求数据做持久化操作,对消息队列有高可用需求。

适用范围:本方案适用于对时间敏感性较低的业务,比如充值、转账业务,在内部系统间就不适合该方式。多适用于跨系统、跨业务、跨网络的服务间数据一致性保证场景。

注意事项:业务被动方暴露给主动方的通知接收接口 以及 业务主动方提供给被动方进行查询操作的接口均需要实现幂等,这样才能保证数据完整性不会被破坏,从而实现最终一致性。

 

2、本地消息表

核心思想:将分布式事务拆分成本地事务进行处理,然后通过定时轮询待发送的消息,直到发送成功。

目的:避免”业务处理成功 + 事务消息发送失败",或"业务处理失败 + 事务消息发送成功"的棘手情况出现,保证 2 个系统事务的数据一致性。

 

优点: 避免了分布式事务,实现了最终一致性。在 .NET中 有现成的解决方案。

缺点: 耦合度高,注意重试时的幂等性操作。

对于消息的生产者,屡次失败的消息,可以设置最大失败次数,超过最大失败次数的消息,不进行接口调用,等待人工处理

对于消息的消费者,如果是业务上面的失败,可以给生产方发送一个业务补偿消息,通知生产方进行回滚等操作。

 

 

3、事务消息

参考:

https://blog.51cto.com/u_13626762/4990938

https://blog.csdn.net/Weixiaohuai/article/details/123733518

https://zhuanlan.zhihu.com/p/115553176?utm_source=wechat_timeline

事务消息:事务消息发送成功后,处于 prepared 状态,不能被订阅者消费,等到事务消息的状态更改为可消费状态后,下游订阅者才可以监听到次消息。

Apache RocketMQ 4.3之后的版本正式支持事务消息,为分布式事务实现提供了便利性支持。在RocketMQ 4.3后实现了完整的事务消息,

实际上其实是对本地消息表的一个封装,将本地消息表移动到了MQ内部,解决 Producer 端的消息发送与本地事务执行的原子性问题。

 

1)事务发起方发送Half事务消息
2)RocketMq回复Half发送成功
3)事务发起方执行本地事务
4)事务发起方执行本地事务成功,发送commit到RocketMq,mq投递消息到事务参与方;

     事务发起方执行本地事务失败,发送rollback到RocketMq,mq删除消息。
5)当RocketMq一定时间内未收到来自事务发起方的确认信息,会对事务发起方进行事务回查
6)事务发起方查询本地事务状态。
7)事务发起方根据查询到的事务状态发送commint/rollback到RocketMq。
8,9,10)当RocketMq发起commit后,收到失败或一定时间未收到成功ack,则会发起重试。

优点

消息数据独立存储,降低业务系统与消息系统之间的耦合。
吞吐量优于本地消息表方案。

缺点

一次消息发送需要两次网络请求(half消息 + commit/rollback)。
需要实现消息回查接口。

注意的问题:

有可能会消息重复投递。消费者需要保证幂等。

解决方式:消费端增加消息应用状态表,用于记录消息的消费情况,每次来一个消息,在真正执行之前,先去消息应用状态表中查询一遍,如果找到说明是重复消息,丢弃即可,如果没找到才执行,同时插入到消息应用状态表(同一事务)。

rocketMQ可视化服务:https://github.com/apache/rocketmq-dashboard

springBoot集成:https://blog.csdn.net/Juzipi1234/article/details/121155769    https://blog.csdn.net/weixin_39643007/article/details/126620127

解决办法:https://blog.csdn.net/shuiyuyue/article/details/124299620   https://blog.csdn.net/sinat_34349564/article/details/116301966

start mqnamesrv.cmd

start mqbroker.cmd -n 10.1.100.68:9876 autoCreateTopicEnable=true -c ../conf/broker.conf

 

 

 

4、TCC

参与:

https://www.bilibili.com/video/BV1pK411s7MS/?spm_id_from=333.337.search-card.all.click

https://blog.csdn.net/zjj2006/article/details/125380752

https://www.sdk.cn/details/EmGNy6EYwpyl6WewAX

https://www.cnblogs.com/xxbiao/p/11679577.html

4.1 TCC原理

 

 

4.2 Seata TCC原理

 

一阶段:Try 阶段: 调用 Try 接口,尝试执行业务,完成所有业务检查,预留业务资源。

二阶段:Confirm 或 Cancel 阶段: 两者是互斥的,只能进入其中一个,并且都满足幂等性,允许失败重试。

               Confirm 操作: 对业务系统做确认提交,确认执行业务操作,不做其他业务检查,只使用 Try 阶段预留的业务资源。
               Cancel 操作: 在业务执行错误,需要回滚的状态下执行业务取消,释放预留资源。

               TCC 中会添加事务日志,如果 Confirm 或者 Cancel 阶段出错,则会进行重试,所以这两个阶段需要支持幂等;如果重试失败,则需要人工介入进行恢复和处理等

以转账为例:

 

优点:
       效率高:TCC 模式在 try 阶段的锁定资源并不是真正意义上的锁定,而是真实提交了本地事务,将资源预留到中间态,并不需要阻塞等待,因此效率比其他模式要高。

      异步提交:try 阶段成功后,不立即进入 confirm/cancel 阶段,而是认为全局事务已经结束了,启动定时任务来异步执行 confirm/cancel,扣减或释放资源,这样会有很大的性能提升。

TCC 模式中需要解决的三个问题:

  (1)幂等:在 commit/cancel 阶段,因为 TC 没有收到分支事务的响应,需要进行重试,这就要分支事务支持幂等。

  (2)空回滚:因为网络问题,try还未执行,先执行了rollback阶段。

  (3)悬挂:因为网络问题,RM 开始没有收到 try 指令,但是执行了 Rollback 后 RM 又收到了 try 指令并且预留资源成功,这时全局事务已经结束,最终导致预留的资源不能释放。

 

 

5、XA

参考:

https://blog.csdn.net/qq_45594962/article/details/126796903

https://blog.csdn.net/web__404/article/details/127971994

5.1 什么是XA

XA是一个分布式事务协议,由Tuxedo提出。XA中大致分为两部分:事务管理器和本地资源管理器。其中本地资源管理器往往由数据库实现,比如Oracle、DB2这些商业数据库都实现了XA接口,而事务管理器作为全局的调度者,负责各个本地资源的提交和回滚。XA实现分布式事务的原理如下:

 

优点:

  • 事务的强一致性,满足ACID原则。

  • 常用数据库都支持,实现简单,并且没有代码侵入

缺点:

  • 因为一阶段需要锁定数据库资源,等待二阶段结束才释放,性能较差

  • 依赖关系型数据库实现事务

5.2XA事务语法

以Mysql为例:xa 可以分为外部XA 和内部XA,外部XA 就是分布式事务,而内部XA,主要是保证同一个MySQL Server 下的各个数据库实例的全局事务一致性。

 

# 在mysql实例中开启一个XA事务,指定一个全局唯一标识;
mysql> XA START 'any_unique_id';

# XA事务的操作结束;
mysql> XA END 'any_unique_id';

# 告知mysql准备提交这个xa事务;
mysql> XA PREPARE 'any_unique_id';

# 告知mysql提交这个xa事务;
mysql> XA COMMIT 'any_unique_id';

# 告知mysql回滚这个xa事务;
mysql> XA ROLLBACK 'any_unique_id';

# 查看本机mysql目前有哪些xa事务处于prepare状态;
mysql> XA RECOVER;

分别在两个库中执行以下操作:

 

5.3 Seata XA

 

 

6、AT

参考:

AT一阶段:

 

Seata会拦截业务SQL,首先解析SQL语义,找到要更新的业务数据,在数据更新前,保存undo log,然后执行业务SQL,更新数据。

更新数据后,保存redo log,最后生成锁,这些操作都是在本地数据库事务内完成,这样保证了异阶段的原子性。

AT二阶段:

如果TC 收到全局事务提交指令后,则TC通知多个RM异步清理本地的事务日志。

TC 收到全局事务提交/回滚指令后,则TC通知每个RM回滚数据。

如果一阶段中有本地事务没有通过,name就执行全局回滚,否则全部提交。回滚用到的是一阶段的undo log,通过回滚记录生成返乡更新

SQL并执行,已完成分支事务的回滚,释放所有的资源和删除所有的日志。

 

问题1:脏读

问题2:脏写

 

7、SAGA

参考:

http://seata.io/zh-cn/docs/user/saga.html

https://www.bilibili.com/video/BV1zU4y1M7HH/?spm_id_from=333.337.search-card.all.click

https://blog.csdn.net/w1014074794/article/details/116997363

https://blog.csdn.net/zh2508/article/details/115441217

https://help.aliyun.com/document_detail/172550.htm?spm=a2c4g.11186623.0.0.163567d6v9QoNH#topic-2027609

7.1 什么是saga

SAGA其核心思想是将长事务拆分为多个本地短事务,由Saga事务协调器协调,如果正常结束那就正常完成,如果某个步骤失败,则根据相反顺序一次调用补偿操作。

 

Saga包含两类:协同式和编排式。

协同式把流程的走向与协调全盘由事务的参考者来完成,比如最简单的场景:下单同时对库存进行扣减,订单服务本地事务完成后就把事件消息发送给库存服务,库存服务如果本地事务处理失败则由它将回滚的消息发送给订单服务。

   虽然整个流程当中订单服务与库存服务并没有产生耦合,但由于没 有一个总的事务协调者,一旦服务参与者多起来那业务流程的可理解性就非常差,出了问题也不好定位。

编排式通过把Saga的执行顺序交由一个集中的Saga编排器,由它指挥并决策业务的流向,相对于协同式整个流程要清晰很多。

适用场景:

  • 业务流程长、业务流程多 ,实现上对业务侵入低,所以非常适合微服务架构的场景。同时 Saga 采用的是一阶段提交模式,不会对资源长时间加锁,不存在“木桶效应”,所以采用这种模式架构的系统性能高、吞吐高。
  • 参与者包含其它公司或遗留系统服务,无法提供 TCC 模式要求的三个接口
  • 松耦合

优势:

  • 一阶段提交本地事务,无锁,高性能
  • 事件驱动架构,参与者可异步执行,高吞吐
  • 补偿服务易于实现
  • 难理解

缺点:

  • 不保证隔离性

需要解决的问题:

          (1)允许空补偿:务设计时需要允许空补偿, 即没有找到要补偿的业务主键时返回补偿成功并将原业务主键记录下来

    • 空补偿:原服务未执行,补偿服务执行了
    • 出现原因:
      • 原服务 超时(丢包)
      • Saga 事务触发 回滚
      • 未收到 原服务请求,先收到 补偿请求

    (2)防悬挂控制:检查当前业务主键是否已经在空补偿记录下来的业务主键中存在,如果存在则要拒绝服务的执行

    • 悬挂:补偿服务 比 原服务 先执行
    • 出现原因:
      • 原服务 超时(拥堵)
      • Saga 事务回滚,触发 回滚
      • 拥堵的 原服务 到达

    (3)幂等控制

    • 原服务与补偿服务都需要保证幂等性, 由于网络可能超时, 可以设置重试策略,重试发生时要通过幂等控制避免业务数据重复更新

7.2 Seata saga

seata提供的Saga模式是基于状态机引擎来实现的,机制是:

1)通过状态图来定义服务调用的流程并生成 json 状态语言定义文件

2)状态图中一个节点可以是调用一个服务,节点可以配置它的补偿节点

3)状态图 json 由状态机引擎驱动执行,当出现异常时状态引擎反向执行已成功节点对应的补偿节点将事务回滚

4)可以实现服务编排需求,支持单项选择、并发、子流程、参数转换、参数映射、服务执行状态判断、异常捕获等功能

seata saga 状态机设计:http://seata.io/saga_designer/index.html#/

实现步骤:

1)数据库表设计:seata_state_machine_def:存储状态机定义文件

seata_state_machine_inst:存储状态机运行实例

seata_state_inst:存储状态图中单个节点

2)代码:



 

标签:事务,XA,业务,回滚,消息,https,分布式
From: https://www.cnblogs.com/maohuidong/p/17540561.html

相关文章

  • 风电分布式并网模型 Wind Farm Simulation Model。 Matlab/simulink
    风电分布式并网模型WindFarmSimulationModel。Matlab/simulink1、共2个火电厂,4个风电场,共15个节点。火电厂:1号火电厂,设定为SwingBus;2号火电厂,设定为PVBus。(在汽轮机调节器可进行调节励磁系统的控制方式)风电厂:4个风电厂;各个风电厂的风速可......
  • 分布式锁面试
    分布式锁是为了解决分布式服务节点间对共享资源的读写问题而产生的。分布式锁实现方式有几种?各有哪些优缺点?1)数据库mysqlinnodb(行锁)   创建表结构createtableifnotexistsdis_table_lock(`id`intprimarykey,`resname`varchar(10),`locker`......
  • spring中的@Transactional声明式事务
     1与编程式事务区别1.1声明式事务使用@Transactional注解来实现事务创建的,spring会为加了事务配置的类创建一个代理对象,基于动态代理,通过其中参数来控制事务的传播、事务回滚等。加在类上相当于给类中所有方法都添加事务。使用声明式事务的好处是使用简单,减少很多像是开......
  • 基于redis的分布式锁
     1为什么要使用分布式锁的理解分布式架构图:例1:在电商业务采用分布式架构后,程序部署在3个tomcat容器中(1个tomcat容器代表一个服务器,3个tomcat可理解在北京上海深圳都有部署电商服务),成员变量A代表商品数量。在北京的Alice,上海的Bob,深圳的Tom,都分别发起了购买或取消iPhone12......
  • Redis事务和持久化机制
    Redis031Redis事务Redis通过multi、exec、watch等命令实现事务功能。Redis的事务功能相对较弱,无法和关系型数据库的事务相媲美。1.1multi和exec命令语法:multi开始事务命令1命令2...exec 执行事务示例:127.0.0.1:6379>multi //开始事务OK127......
  • 分布式锁及其实现
    分布式锁1.锁有限资源的情况下,控制同一时间(段)只有某些线程(用户/服务器)能访问到资源。Java实现锁:synchronized关键字、并发包的类问题:只对单个JVM有效2.分布式锁为啥需要分布式锁?有限资源的情况下,控制同一时间(段)只有某些线程(用户/服务器)能访问到资源。单个锁只......
  • Seata 分布式事务 XA 与 AT 全面解析
    目录XA模式是什么?什么是Seata的事务模式?AT模式是什么?为什么Seata要支持XA模式?AT与XA之间的关系总结1.XA模式是什么?首先正如煊檍兄所言,了解了什么是XA与什么是Seata定义的事务模式,便一目了然。1.1什么是XA用非常官方的话来说XA规范是X/Open组织定义的分布式事务处理(DTP,Distr......
  • mysq事务、日志
    --实现事务的两种方式--关闭事务自动提交手动commit--开启事务然后提交--事务的四大特性--原子性(不可分割,要么全部成功,要么全部失败)--一致性(事务完成时,所有数据保证一致状态)--隔离性(数据库系统提供的隔离机制,保证事务在不受外部并发操作影响的独立环境下运......
  • 分布式 id
    随着业务的增长,文章表可能要占用很大的物理存储空间,为了解决该问题,后期使用数据库分片技术。将一个数据库进行拆分,通过数据库中间件连接。如果数据库中该表选用ID自增策略,则可能产生重复的ID,此时应该使用分布式ID生成策略来生成ID。......
  • 如何实现分布式架构 数据中心 软件有哪些的具体操作步骤
    分布式架构数据中心软件实现流程1.了解分布式架构概念在开始实现分布式架构之前,首先需要了解什么是分布式架构。分布式架构是一种将系统拆分成多个小模块,运行在多个物理或虚拟机器上的架构方式。每个模块可以独立运行,并通过网络通信进行交互。分布式架构可以提高系统的可伸缩......