分布式事务相关理论

1 事务简介

事务 (Transaction) 是操作数据库中某个数据项的一个程序执行单元(unit)。事务应该具有 4 个属性:原子性、一致性、隔离性、持久性。这四个属性通常称为 ACID 特性。

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

事务在执行过程中发生错误,会被回滚(Rollback)到事务开始前的状态,就像这个事务从来没有执行过一样。
比方说:买东西要么交钱收货一起都执行,要么发不出货,就退钱

(2)一致性(consistency):事务必须是使数据库从一个一致性状态变到另一个一致性状态。一个事务查看数据时,数据所处的状态要么是另一事务修改它之前的状态,要么是另一事务修改它之后的状态,事务不会查看到中间状态的数据。

如果事务成功地完成,那么系统中所有变化将正确地应用,系统处于有效状态。
如果在事务中出现错误,那么系统中的所有变化将自动地回滚,系统返回到原始状态。

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

比方说:一个人买东西这个事情,是不影响其他人买东西。
隔离性又分为四个级别:读未提交 (read uncommitted)、读已提交 (read committed,解决脏读)、可重复读 (repeatable read,解决虚读)、串行化 (serializable,解决幻读)。

(4)持久性(durability):持久性也称永久性(permanence),指一个事务一旦提交,它对数据库中数据的改变就应该是永久性的。接下来的其他操作或故障不应该对其有任何影响。即使发生系统崩溃,重新启动数据库系统后,数据库还能恢复到事务成功结束时的状态。

比方说:一个人买东西的时候需要记录在账本上,即使老板忘记了那也有据可查。

2 MySQL的事务实现方案

大多数场景下,我们的应用都只需要操作单一的数据库,这种情况下的事务称之为本地事务 (Local Transaction)。本地事务的 ACID 特性是数据库直接提供支持。

大部分人对 MySQL 都比较熟悉,以 MySQL 的 InnoDB (InnoDB 是 MySQL 的一个存储引擎)为例,InnoDB 是通过 日志和锁 来保证的事务的 ACID 特性,具体如下:

  • (1)通过数据库锁的机制,保障事务的隔离性;
  • (2)通过 Redo Log(重做日志)来,保障事务的持久性;
  • (3)通过 Undo Log (撤销日志)来,保障事务的原子性;
  • (4)通过 Undo Log (撤销日志)来,保障事务的一致性;

Undo Log 如何保障事务的原子性呢?

具体的方式为:在操作任何数据之前,首先将数据备份到一个地方(这个存储数据备份的地方称为 Undo Log),然后进行数据的修改。如果出现了错误或者用户执行了 Rollback 语句,系统可以利用 Undo Log 中的备份将数据恢复到事务开始之前的状态。

Redo Log 如何保障事务的持久性呢?

具体的方式为:Redo Log 记录的是新数据的备份(和 Undo Log 相反)。在事务提交前,只要将 Redo Log 持久化即可,不需要将数据持久化。当系统崩溃时,虽然数据没有持久化,但是 Redo Log 已经持久化。系统可以根据 Redo Log 的内容,将所有数据恢复到崩溃之前的状态。

3 什么是分布式事务?

在分布式系统上一次大的操作由不同的小操作组成,这些小的操作分布在不同的服务节点上,且属于不同的应用,分布式事务需要保证这些小操作要么全部成功,要么全部失败。

典型的分布式事务场景:

  1. 跨库事务
  2. 分库分表
  3. 服务化 (SOA)

4 CAP 定理

CAP 定理是由加州大学伯克利分校 Eric Brewer 教授提出来的,他指出 WEB 服务无法同时满足一下 3 个属性:

  • 一致性 (Consistency) : 客户端知道一系列的操作都会同时发生 (生效)
  • 可用性 (Availability) : 每个操作都必须以可预期的响应结束,返回成功或失败
  • 分区容错性 (Partition tolerance) : 即使出现单个组件无法可用,操作依然可以完成
4.1 数据一致性

数据一致性分为强一致性、弱一致性、最终一致性

  • 如果的确能像上面描述的那样时刻保证客户端看到的数据都是一致的,那么称之为强一致性
  • 如果允许存在中间状态,只要求经过一段时间后,数据最终是一致的,则称之为最终一致性
  • 此外,如果允许存在部分数据不一致,那么就称之为弱一致性。
4.2 可用性

系统提供的服务必须一直处于可用的状态,对于用户的每一个操作请求总是能够在有限的时间内返回结果,如果超时,那么系统就被认为是不可用的

4.3 分区容错性

分布式系统在遇到任何网络分区故障的时候,仍然需要能够保证对外提供满足一致性和可用性的服务,除非是整个网络环境都发生了故障。

分区容错性是不能被抛弃的那个,只能在一致性、可用性寻找平衡。大部分互联网公司采可能会优先采用这基于 BASE 理论的柔性事务,强调的是可用性。

5 BASE 理论

即使无法做到强一致性,但应用可以采用适合的方式达到最终一致性。

BASE 是 Basically Available(基本可用)、Soft state(软状态)和 Eventually consistent(最终一致性)三个短语的缩写。

1.基本可用(Basically Available)
指分布式系统在出现不可预知故障的时候,允许损失部分可用性。

2.软状态( Soft State)
指允许系统中的数据存在中间状态,并认为该中间状态的存在不会影响系统的整体可用性。

3.最终一致( Eventual Consistency)
强调的是所有的数据更新操作,在经过一段时间的同步之后,最终都能够达到一个一致的状态。因此,最终一致性的本质是需要系统保证最终数据能够达到一致,而不需要实时保证系统数据的强一致性。

6 分布式事务的主要方案

BAS 柔性事务方案有:

  • 本地消息表
  • 可靠消息最终一致性方案 (mq)
  • 最大努力通知方案
  • TCC(两阶段型、补偿型)

CAP 理论的事务方案(强一致)有:

  • 两阶段提交方案 XA 方案
7 TCC 方案

TCC 方案的全称是:Try、Confirm、Cancel。

  • Try 阶段:对各个服务的资源做检测以及对资源进行锁定或者预留。
  • Confirm 阶段:在各个服务中执行实际的操作。
  • Cancel 阶段:如果任何一个服务的业务方法执行出错,那么这里就需要进行补偿动作。补偿动作具体来说,就是对已经执行成功的业务逻辑的回滚操作。

TCC 方案严重依赖回滚和补偿代码,最终的结果是:回滚代码逻辑复杂,业务代码很难维护。所以,TCC 方案的使用场景较少,主要用于支付、交易相关的场景。

7 最终一致性方案


(1)A 系统先发送一个 prepared 消息到 mq,如果这个 prepared 消息发送失败那么就直接取消操作别执行了;

(2)如果这个消息发送成功过了,那么接着执行本地事务,如果成功就告诉 mq 发送确认消息,如果失败就告诉 mq 回滚消息;

(3)如果发送了确认消息,那么此时 B 系统会接收到确认消息,然后执行本地的事务;

(4)mq 会自动定时轮询所有 prepared 消息回调你的接口,问你,这个消息是不是本地事务处理失败了,所有没发送确认的消息,是继续重试还是回滚?一般来说这里你就可以查下数据库看之前本地事务是否执行,如果回滚了,那么这里也回滚吧。这个就是避免可能本地事务执行成功了,而确认消息却发送失败了。

(5)这个方案里,要是系统 B 的事务失败了咋办?重试咯,自动不断重试直到成功,如果实在是不行,要么就是针对重要的资金类业务进行回滚,比如 B 系统本地回滚后,想办法通知系统 A 也回滚;或者是发送报警由人工来手工回滚和补偿。

这个还是比较合适的,目前国内互联网公司大都是这么玩儿的,要不你举用 RocketMQ 支持的,要不你就自己基于类似 ActiveMQ?RabbitMQ?自己封装一套类似的逻辑出来,总之思路就是这样子的。

8 面试中如何应答?

TCC 和可靠消息最终一致性方案是在生产中最常用。

对于那些特别严格的场景,用的是 TCC 来保证强一致性;阿里开源了分布式事务框架,seata类似TCC事务,经历过阿里生产环境大量考验的框架。seata支持Dubbo,Spring Cloud。

对于数据一致性要求没有那些特别严格的场景,可以使用可靠消息最终一致性方案,如果基于 RocketMQ 来实现了分布式事务框架,
RocketMQ提供了分布式事务支持,已经把可靠消息服务需要实现的功能逻辑已经做好了。
也可以基于 ActiveMQ,RabbitMQ,等,自己开发一个可靠消息服务,收到消息之后,尝试投递到 MQ,如果投递失败,重试投递

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

占星安啦

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值