怎么实现分布式事务?

1.什么是事务?

  事务应该具有4个属性:原子性、一致性、隔离性、持久性。这四个属性通常称为ACID特性

        原子性(atomicity)。一个事务是一个不可分割的工作单位,事务中包括的操作要么都做,要么都不做。

        一致性(consistency)。事务必须是使数据库从一个一致性状态变到另一个一致性状态。一致性与原子性是密切相关的。

        隔离性(isolation)。一个事务的执行不能被其他事务干扰。即一个事务内部的操作及使用的数据对并发的其他事务是隔离的,并发执行的各个事务之间不能互相干扰。

        持久性(durability)。持久性也称永久性(permanence),指一个事务一旦提交,它对数据库中数据的改变就应该是永久性的。接下来的其他操作或故障不应该对其有任何影响。

2.什么是分布式事务?

    简单的说,就是一个大操作,由很多小操作组成,而这些小操作又分布在不同的服务器上,分布式事务就是需要保证这些小操作要么全部成功,要么全部失败。

3.在此之前要了解一下CAP定理,不会的人请转到我另一篇文章

   https://blog.csdn.net/weixin_49100429/article/details/119727069

4.分布式能否兼顾CAP?

        在保证分区容忍性的前提下一致性和可用性无法兼顾,如果要提高系统的可用性就要增加多个结点,如果要保证数据的一致性就要实现每个结点的数据一致,结点越多可用性越好,但是数据一致性越差。所以,在进行分布式系统设计时,同时满足“一致性”、“可用性”和“分区容忍性”三者是几乎不可能的。

CAP有哪些组合方式?
1、CA:放弃分区容忍性,加强一致性和可用性,关系数据库按照CA进行设计。
2、AP:放弃一致性,加强可用性和分区容忍性,追求最终一致性,很多NoSQL数据库按照AP进行设计。说明:这里放弃一致性是指放弃强一致性,强一致性就是写入成功立刻要查询出最新数据。追求最终一致性是指允许暂时的数据不一致,只要最终在用户接受的时间内数据 一致即可
3、CP:放弃可用性,加强一致性和分区容忍性,一些强一致性要求的系统按CP进行设计,比如跨行转账,一次转账请求要等待双方银行系统都完成整个事务才算完成。​ 说明:由于网络问题的存在CP系统可能会出现待等待超时,如果没有处理超时问题则整理系统会出现阻塞

5.分布式事务的解决方案有以下几种

2PC(二阶段提交)

两阶段提交协议(2 Phase Commitment Protocol),两阶段提交由协调者和参与者组成,共经过两个阶段和三个操作,部分关系数据库如Oracle、MySQL支持两阶段提交协议,简单画个图

1)第一阶段:准备阶段(prepare)
协调者通知参与者准备提交,各参与者反馈事务执行结果,但参与者先不提交事务。
2)第二阶段:提交(commit)/回滚(rollback)阶段
协调者通知参与者开始提交,各参与者反馈事务提交结果。只要在这两个阶段中执行结果和提交结果有失败回复,整个事务回滚
2PC的优点:实现强一致性,部分关系数据库支持(Oracle、MySQL等)。
缺点:整个事务的执行需要由协调者在多个节点之间去协调,增加了事务的执行时间,性能低下。

3PC(三阶段提交)

与两阶段提交不同的是,三阶段提交有两个改动点。
1)引入超时机制。同时在协调者和参与者中都引入超时机制。

2)在第一阶段和第二阶段中插入一个准备阶段。保证了在最后提交阶段之前各参与节点的状态是一致的。也就是说,除了引入超时机制之外,3PC把2PC的准备阶段再次一分为二,这样三阶段提交就有CanCommit、PreCommit、DoCommit三个阶段。

阶段一:CanCommit
事务询问 执行者向所有参与者发送CanCommit请求,等待所有参与者的响应
参与者反馈响应 参与者节点若认为自身可以完成事务,返回Yes;反之,返回No
阶段二:PreCommit
若所有参与者反馈的结果都是Yes响应,那么进行事务预提交
若任意一个参与者反馈的结果是No响应,或者在等待超时之后,那么执行事务中断
阶段三:doCommit
该阶段可能存在两种情况,执行事务的提交和中断事务
若执行者接受到所有参与的ACK响应,那么执行事务提交
如果有任意一个参与者反馈No响应,或者在等待超时之后,执行中断事务

TCC(事务补偿)

TCC事务补偿是基于2PC实现的业务层事务控制方案,它是TryConfirmCancel三个单词的首字母,含义如下:
1、Try 检查及预留业务资源完成提交事务前的检查,并预留好资源。
2、Confirm确定执行业务操作对try阶段预留的资源正式执行。
3、Cancel取消执行业务操作对try阶段预留的资源释放。

核心思想:

针对每个操作,都要注册一个与其对应的确认和补偿(撤销)操作。分为三个阶段

简单来说

1.先来Try一下,不要把业务逻辑完成,先试试看,看各个服务能不能基本正常运转,能不能先冻结我需要的资源。

2.如果Try都ok,也就是说,底层的数据库、redis、elasticsearch、MQ都是可以写入数据的,并且你保留好了需要使用的一些资源(比如冻结了一部分库存)。

3.接着,再执行各个服务的Confirm逻辑,基本上Confirm就可以很大概率保证一个分布式事务的完成了。

4.那如果Try阶段某个服务就失败了,比如说底层的数据库挂了,或者redis挂了,等等。
此时就自动执行各个服务的Cancel逻辑,把之前的Try逻辑都回滚,所有服务都不要执行任何设计的业务逻辑。保证大家要么一起成功,要么一起失败。

优点:最终保证数据的一致性,在业务层实现事务控制,灵活性好。

缺点:开发成本高,每个事务操作每个参与者都需要实现try/confirm/cancel三个接口。

什么是幂等性?

幂等性是指同一个操作无论请求多少次,其结果都相同。
幂等操作实现方式有:
1、操作之前在业务方法进行判断如果执行过了就不再执行。
2、缓存所有请求和处理的结果,已经处理的请求则直接返回结果。
3、在数据库表中加一个状态字段(未处理,已处理),数据操作时判断未处理时再处理

消息队列实现最终一致性

消息事务其实就是基于消息中间件的两阶段提交,将本地事务和发消息放在同一个事务里,保证本地操作和发送消息同时成功

采用最终一致性原理。
需要保证以下三要素:
1、确认生产者一定要将数据投递到MQ服务器中(采用MQ消息确认机制)
2、MQ消费者消息能够正确消费消息,采用手动ACK模式(注意重试幂等性问题)
3、如何保证第一个事务先执行,采用补偿机制,在创建一个补单消费者进行监听,如果订
单没有创建成功,进行补单。(如果第一个事务中出错,补单消费者会在重新执行一次第一个
事务,例如第一个事务是添加订单表,如果失败在补单的时候重新生成订单记录,由于订单号
唯一,所以不会重复)

经典案例,以目前流行点外卖的案例,用户下单后,调用订单服务,让后订单服务调用派单系
统通知送外卖人员送单,这时候订单系统与派单系统采用MQ异步通讯。

MQ解决分布式事务一致性

  • 3
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值