单库拆分为分库分表之后,一个巨大的挑战就是本地事务变成了分布式事务。事实上,即使没有分库分表,在微服务架构之下我们也还是会面临分布式事务的问题。
#
分布式事务既可以是纯粹多个数据库实例之间的分布式事务,也可以是跨越不同中间件的业务层面上的分布式事务。前表一般是分库分表中间件提供支持,后者一般是独立的第三方中间件提供支持,比如Seata。在面试的时候,要根据上下文确定面试官问你的分布式事务是哪一类。
先介绍分布式事务中几个比较常用的协议
三阶段提交协议是在两阶段协议地基础上进行地改进,三阶段提交协议引入了一个额外阶段来确保执行事务之前有足够的资源,减少两阶段协议引起的事务失败的可能。
在两阶段协议里面,比较容易出现的一个情况就是参与者在准备阶段辛辛苦苦把Redo,Undo
写好,结果另外一个参与者说自己这边执行不了事务,要回滚。那么这个参与者就白费功夫了。
因此在两阶段提交的基础上,三阶段提交引入了一个新阶段,协调者会先问一下参与者能不能执行这个事务。所以,整个三阶段提交协议的三个阶段是这样的
- 第一阶段
CanCommit
:协调者问一下各个参与者能不能执行事务。参与者这时候一般是检查一下自己有没有足够的资源。 - 第二阶段
PreCommit
:类似两阶段提交的第一个阶段,执行事务但是不提交 - 第三阶段
Commit
:直接提交或回滚
目前来看,三阶段提交协议并没有两阶段提交协议使用得那么广泛,原因有两个:一是两阶段提交协议已经足以解决大部分问题了,二是三阶段提交得收益和它得复杂度比起来,性价比有点低