概述
分布式事务入门
一、为什么会产生分布式事务
我们从单体架构不断的演变成为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发送到消息的消 费方。如果消息发送失败,会进行重试发送。
消息消费方,需要处理这个消息,并完成自己的业务逻辑。此时如果本地事务处理成 功,表明已经处理成功了,如果处理失败,那么就会重试执行。
如果是业务上面的失 败,可以给生产方发送一个业务补偿消息,通知生产方进行回滚等操作。 生产方和消费方定时扫描本地消息表,把还没处理完成的消息或者失败的消息再发送一 遍。
如果有靠谱的自动对账补账逻辑,这种方案还是非常实用的。
优点: 一种非常经典的实现,避免了分布式事务,实现了最终一致性。
缺点: 消息表会耦合到业务系统中,如果没有封装好的解决方案,会有很多杂活需要处理。
总结:
分布式事务是一个复杂的问题,我这里只是简单做一下介绍,如果有不当之处,欢迎指正;
最后
以上就是虚拟毛衣为你收集整理的分布式事务入门的全部内容,希望文章能够帮你解决分布式事务入门所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复