前言
因为公司的项目用到了分布式事物
,一开始对这个概念了解的只是模棱两可,所以自己学习了一波并整理了此篇博客。众所周知,分布式事务是企业集成中的一个技术难点,也是每一个分布式系统架构中都会涉及到的一个东西,尤其是在微服务中分布式事物
是必须要解决的一个课题。
All or Nothing
- 在了解
分布式事物
之前,有必要复习一下数据库本地事物。
事务提供一种机制将一个活动涉及的所有操作纳入到一个不可分割的执行单元,组成事务的所有操作只有在所有操作均能正常执行的情况下方能提交,只要其中任一操作执行失败,都将导致整个事务的回滚。简单地说,事务提供一种“要么什么都不做,要么做全套(All or Nothing)”机制。 - 事物的四大特性(ACID)
- A 原子性(Atomicity):一个事务(transaction)中的所有操作,要么全部完成,要么全部不完成,不会结束在中间某个环节。
- C 一致性(Consistency),事务的一致性指的是在一个事务执行之前和执行之后数据库都必须处于一致性状态。
- I 隔离性(Isolation),指的是在并发环境中,当不同的事务同时操纵相同的数据时,每个事务都有各自的完整数据空间。
- D 持久性(Durability),指的是只要事务成功结束,它对数据库所做的更新就必须永久保存下来。
- 在MySQL中,本地事物是如何实现的
- 事务的 ACID 是通过 InnoDB 日志和锁来保证。事务的隔离性是通过数据库锁的机制实现的,持久性通过 Redo Log(重做日志)来实现,原子性和一致性通过 Undo Log 来实现。
- Undo Log 的原理很简单,为了满足事务的原子性,在操作任何数据之前,首先将数据备份到一个地方(这个存储数据备份的地方称为 Undo Log)。然后进行数据的修改。
- 如果出现了错误或者用户执行了 Rollback 语句,系统可以利用 Undo Log 中的备份将数据恢复到事务开始之前的状态。
- 和 Undo Log 相反,Redo Log 记录的是新数据的备份。在事务提交前,只要将 Redo Log 持久化即可,不需要将数据持久化。
- 当系统崩溃时,虽然数据没有持久化,但是 Redo Log 已经持久化。系统可以根据 Redo Log 的内容,将所有数据恢复到最新的状态。
分布式理论
-
官方说法:分布式事务指事务的参与者、支持事务的服务器、资源服务器以及事务管理器分别位于不同的分布式系统的不同节点之上。
-
个人理解:就是一个大的事物由不同的小事物组合而来,分布式事务的工作就是保证这些小事物要么全部成功,要么全部失败。
-
CAP理论
- CAP定理是由加州大学伯克利分校Eric Brewer教授提出来的,他指出数据库设计时无法同时满足一下3个属性:
- 一致性(Consistency) : 客户端知道一系列的操作都会同时发生
- 可用性(Availability) : 每个操作都必须以可预期的响应结束
- 分区容错性(Partition tolerance) : 即使出现单个组件无法可用,操作依然可以完成
- CAP定理是由加州大学伯克利分校Eric Brewer教授提出来的,他指出数据库设计时无法同时满足一下3个属性:
CAP理论意思就是在任何数据库设计中,都无法同时满足这三个特性,最多只能同时支持两个特性并存。很显然,在设计数据库的时候,就需要在三个特性之间进行取舍,也就是说必须在一致性与可用性之间做出选择
。
- BASE理论
在分布式系统中,我们往往追求的是可用性,所以可用性的优先级明显高于一致性。因此前辈们给我们我们提出来了另外一个理论,就是BASE理论,它是用来对CAP定理进行进一步扩充的,是对CAP中AP的一个扩展。BASE理论指的是:- Basically Available(基本可用)
- Soft state(软状态)
- Eventually consistent(最终一致性)
那么BASE理论是什么意思呢:数据库设计时无法做到强一致,但每个小应用都可以根据自身的业务特点,采用适当的方式来使系统达到最终一致性。很明显BASE理论和ACID是相反的,它完全不同于ACID的强一致性模型,而是通过牺牲强一致性来获得可用性,并允许数据在一段时间内是不一致的,但最终达到一致状态。
分布式事物解决方案
分布式事物的基本理论写的差不多了,接下来了解一下常见的解决方案。
-
两阶段提交(2PC)
在了解2PC之前,简单了解一下分布式事务中的 XA Transactions,在 XA 协议中分为两阶段-
事务管理器要求每个涉及到事务的数据库预提交(precommit)此操作,并反映是否可以提交。
-
事务协调器要求每个数据库提交数据,或者回滚数据。
-
2PC的核心思想就是:每个节点都可以知晓自己操作的成功或者失败,却无法知道其他节点操作的成功或失败。需要引入一个协调者(Coordinator)来统一掌控所有参与者(Participant)的操作结果,并指示它们是否要把操作结果进行真正的提交(commit)或者回滚(rollback)。
-
2PC顾名思义分为两个阶段,其实施思路可概括为
- 投票阶段(voting phase):参与者将操作结果通知协调者
- 提交阶段(commit phase):收到参与者的通知后,协调者再向参与者发出通知,根据反馈情况决定各参与者是否要提交还是回滚
-
-
补偿事务(TCC)
TCC事务补偿是基于2PC实现的业务层事务控制方案,它是Try、Confirm和Cancel三个单词的首字母,含义如下:- Try 检查及预留业务资源,完成提交事务前的检查,并预留好资源。
- Confirm 确定执行业务操作,对try阶段预留的资源正式执行。
- Cancel 取消执行业务操作,对try阶段预留的资源释放。
- 举个例子:
- Try 下单业务由订单服务和库存服务协同完成,在try阶段订单服务和库存服务完成检查和预留资源。订单服务检查当前是否满足提交订单的条件(比如:当前存在未完成订单的不允许提交新订单)。 库存服务检查当前是否有充足的库存,并锁定资源。
- Confirm 订单服务和库存服务成功完成Try后开始正式执行资源操作。订单服务向订单写一条订单信息。库存服务减去库存。
- Cancel 如果订单服务和库存服务有一方出现失败则全部取消操作。订单服务需要删除新增的订单信息。库存服务将减去的库存再还原。
- 注意事项:TCC接口都需要实现等幂性。
-
MQ事务消息
在几种常见的分布式事物解决方案中,这中方法可能是最简单的,但是缺点也是最明显的,就是非常的吃MQ的性能,而且有一些MQ不支持,这个方法我没有做过多的研究,所以就不写了。。。
打个广告
GTS-阿里巴巴全新分布式事务解决方案,这是一个基于云的事物中间件,感兴趣的小伙伴可以了解一下。
写在最后
通过自己的学习,对分布式事务中的CAP定理、BASE理论以及经典的解决方案有了一定的了解。微服务过多就会引出分布式事务,如果允许不建议采用上面任何一种方案,而是请把需要事务的微服务聚合成一个单机服务,使用数据库的本地事务。