我是靠谱客的博主 虚拟毛衣,最近开发中收集的这篇文章主要介绍分布式事务入门,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

分布式事务入门

一、为什么会产生分布式事务

我们从单体架构不断的演变成为SOA架构、微服务架构的时候就会一个是事务里包含多个系统,多个数据库的操作,这个时候传统事务就解决不了;

  • 数据库分库分表:在单库单表场景下,当业务数据量达到单库单表的极限时,就需要考虑分库分表,将之前的单库单表拆分成多库多表;分库分表之后,原来在单个数据库上的事务操作,可能就变成跨多个数据库的操作,此时就需要使用分布式事务。
  • 业务服务化:业务服务化即业务按照面向服务(SOA)的架构拆分整个网站系统,所有的业务操作都以服务的方式对外发布,跨应用、跨服务的操作需要使用分布式事务才能保证数据的一致性。

二、解决分布式事务前序

1、CAP原理

由于对服务或者数据库进行了拆分,这里就使用到了分布式的CAP原理;

  • C一致性;
  • A可用性;
  • P分区容错性
    对于分布式系统,分区容错性是一定要满足的,这里就分出来AP和CP两种情况,我们常见的注册中心ZK主要保证了CP,eureka主要保证了AP

2、BASE原理

对于CAP原理的数据一致性,后来又提出了BASE原理,核心思想:即使无法做到强一致性,但每个业务根据自身的特点,采用适当的方式来使系统达到最终一致性。

  • BA:基本一致性,比如流量大的时候,有一部分用户响应不过来,进行了降级处理,但还是有一部分可用的;
  • S:柔性状态
  • E:最终一致性,这里要求幂等性

3、柔性事务与刚性事务

  • 刚性:主要是指那些满足ACID的事务
  • 柔性:
    • 两阶段提交:基于XA协议实现
    • 补偿型TCC:Try/Confirm/Cancel
    • 异步确保型(使用消息中间件)

三、解决分布式事务问题的方案

1、两阶段提交方案:基于XA协议实现

下图为XA规范主要组件:

  • AP:定义事务的边界,即定义了事务开始和结束的边界
  • TM:事务管理器,负责管理全局事务,分配事务唯一标 识,监控事务的执行进度,并负责事务的提交、回滚、失败恢复等。
  • RMs:资源管理器,Rm管理计算机共享的资源,许多软件都可 以去访问这些资源,资源包含比如数据库、文件系统、打印机服务器等。

在这里插入图片描述

第一阶段:TM要求所有的RM准备提交对应的事务分支,询问RM是否有能力保证成功的提交事务分支,RM根据自己的情况,如果判断自己进行的工作可以被提交,那就就对工作内容进行持久化,并给TM回执OK;否者给TM的回执NO。RM在发送了否定答复并回滚了已经的工作后,就可以丢弃这个事务分支信息了。 
第二阶段:TM根据阶段1各个RM prepare的结果,决定是提交还是回滚事务。如果所有的 RM都prepare成功,那么TM通知所有的RM进行提交;如果有RM prepare回执NO的 话,则TM通知所有RM回滚自己的事务分支。 也就是TM与RM之间是通过两阶段提交协议进行交互的. 

优点: 尽量保证了数据的强一致,适合对数据强一致要求很高的关键领域。(其实也不 能100%保证强一致) 
缺点: 实现复杂,牺牲了可用性,对性能影响较大,不适合高并发高性能场景。

注释:常见的XA的解决方案有atomikos;

2、补偿型TCC:核心思想是针对每一个操作,都注册一个与其对应的确认(Confirm)和取消(Concel)操作;

主要分为以下三个步骤:

  • Try 阶段主要是对业务系统做检测及资源预留(比如这里先弄一些预留字段,把资源冻结处理,不进行真正的update)
  • Confirm 阶段主要是对业务系统做确认提交,Try阶段执行成功并开始执行 Confirm 阶段时,默认 Confirm阶段是不会出错的。即:只要Try成功,Confirm一定成功。
  • Cancel 阶段主要是在业务执行错误,需要回滚的状态下执行的业务取消,预留资源 释放。

注释:confirm、cancel阶段可以使用到一些分布式框架(大佬的话,也可以自己写),比如:tcc-transaction、EasyTransaction
https://github.com/QNJR-GROUP/EasyTransaction
https://github.com/changmingxie/tcc-transaction

在这里插入图片描述
例如: A要向 B 转账,思路大概是:
我们有一个本地方法,里面依次调用

1、首先在 Try 阶段,要先调用远程接口把 B和 A的钱给冻结起来。例如在A,B所在账户表中各自新增一个字段,在try阶段不update,而是将转账金额存下来;
2、在 Confirm 阶段,执行远程调用的转账的操作,转账成功进行解冻。 
3、如果第2步执行成功,那么转账成功,如果第二步执行失败,则调用远程冻结接口对应的解 冻方法 (Cancel)。

优点: 相比两阶段提交,可用性比较强 
缺点: 数据的一致性要差一些。TCC属于应用层的一种补偿方式,所以需要程序员在实 现的时候多写很多补偿的代码,在一些场景中,一些业务流程可能用TCC不太好定义及处理。

3、消息中间件:核心思想就是将分布式事务拆分为本地事务进行处理;

在这里插入图片描述

基本思路就是: 
消息生产方,需要额外建一个消息表,并记录消息发送状态。消息表和业务数据要在一 个事务里提交,也就是说他们要在一个数据库里面。
然后消息会经过MQ发送到消息的消 费方。如果消息发送失败,会进行重试发送。 

消息消费方,需要处理这个消息,并完成自己的业务逻辑。此时如果本地事务处理成 功,表明已经处理成功了,如果处理失败,那么就会重试执行。
如果是业务上面的失 败,可以给生产方发送一个业务补偿消息,通知生产方进行回滚等操作。 生产方和消费方定时扫描本地消息表,把还没处理完成的消息或者失败的消息再发送一 遍。
如果有靠谱的自动对账补账逻辑,这种方案还是非常实用的。 

优点: 一种非常经典的实现,避免了分布式事务,实现了最终一致性。 
缺点: 消息表会耦合到业务系统中,如果没有封装好的解决方案,会有很多杂活需要处理。

总结:

分布式事务是一个复杂的问题,我这里只是简单做一下介绍,如果有不当之处,欢迎指正;

最后

以上就是虚拟毛衣为你收集整理的分布式事务入门的全部内容,希望文章能够帮你解决分布式事务入门所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(36)

评论列表共有 0 条评论

立即
投稿
返回
顶部