事务就是用户定义的一系列数据库操作,这些操作可以视为一个完成的逻辑处理工作单元,要么全部执行,要么全部不执行,是不可分割的工作单元。
事务实现应该是具备原子性、一致性、隔离性和持久性,简称 ACID。
而通俗意义上事务就是为了使得一些更新操作要么都成功,要么都失败。
分布式事务顾名思义就是要在分布式系统中实现事务,它其实是由多个本地事务组合而成。
CAP理论指的是在一个分布式系统中,不能同时满足一致性(Consistency)、可用性(Avalibality)、分区容错性(Partition Tolerance)。也称柔性事务,满足ACID则属于刚性事务。
致性(Consistency):数据在多个副本之间能够保持一致的特性(强一致性)。就像Redis的主从结构,Zookeeper的Master/Slave结构,主从之间的数据保持一致,这些都是最终一致性。
可用性(Availability):系统一直处于可用状态,能正常响应数据,但是不保证响应数据为最新数据。
分区容错性(Partition tolerance):分布式系统在遇到网络故障的时候,仍然能够对外提供满足一致性和可用性的服务,除非整个网络环境都发生了故障。
2PC、3PC和TCC
中文叫二阶段提交,是一种强一致性设计。2PC 引入一个事务协调者的角色来协调管理各参与者(也可称之为各本地资源)的提交和回滚,二阶段分别指的是准备(投票)和提交两个阶段。
准备阶段协调者会给各参与者发送准备命令,同步等待所有资源的响应之后就进入第二阶段即提交阶段(注意提交阶段不一定是提交事务,也可能是回滚事务)。
假如在第一阶段所有参与者都返回准备成功,那么协调者则向所有参与者发送提交事务命令,然后等待所有事务都提交成功之后,返回事务执行成功。

假如在第一阶段有一个参与者返回失败,那么协调者就会向所有参与者发送回滚事务的请求,即分布式事务执行失败。

第二阶段执行失败:
第二阶段执行的是回滚事务操作,那么答案是不断重试,直到所有参与者都回滚了,不然那些在第一阶段准备成功的参与者会一直阻塞着。
第二阶段执行的是提交事务操作,那么答案也是不断重试,因为有可能一些参与者的事务已经提交成功了,这个时候只有不断的重试,直到提交成功,到最后真的不行只能人工介入处理。
2PC 是一个同步阻塞协议,像第一阶段协调者会等待所有参与者响应才会进行下一步操作,当然第一阶段的协调者有超时机制,假设因为网络原因没有收到某参与者的响应或某参与者挂了,那么超时后就会判断事务失败,向所有参与者发送回滚命令。
在第二阶段协调者的没法超时,只能不断重试!
协调者故障分析
协调者是一个单点,存在单点故障问题。
假设协调者在发送准备命令之前挂了,还行等于事务还没开始。
假设协调者在发送准备命令之后挂了,有些参与者等于都执行了处于事务资源锁定的状态。不仅事务执行不下去,还会因为锁定了一些公共资源而阻塞系统其它操作。
假设协调者在发送回滚事务命令之前挂了,那么事务也是执行不下去,且在第一阶段那些准备成功参与者都阻塞着。
假设协调者在发送回滚事务命令之后挂了,这个还行,至少命令发出去了,很大的概率都会回滚成功,资源都会释放。但是如果出现网络分区问题,某些参与者将因为收不到命令而阻塞着。
假设协调者在发送提交事务命令之前挂了,所有资源都阻塞着。
假设协调者在发送提交事务命令之后挂了,很大概率都会提交成功,然后释放资源,但是如果出现网络分区问题某些参与者将因为收不到命令而阻塞着。
协调者故障,通过选举得到新协调者
因为协调者单点问题,因此我们可以通过选举等操作选出一个新协调者来顶替。
2PC 适用于数据库层面的分布式事务场景。
3PC 的出现是为了解决 2PC 的一些问题,相比于 2PC 它在参与者中也引入了超时机制,并且新增了一个阶段使得参与者可以利用这一个阶段统一各自的状态。
3PC 包含了三个阶段,分别是准备阶段、预提交阶段和提交阶段。

准备阶段的变更成不会直接执行事务,而是会先去询问此时的参与者是否有条件接这个事务。
预提交阶段的引入起到了一个统一状态的作用,在预处理阶段表明所有参与者都已经回应了。
3PC 的引入是为了解决提交阶段 2PC 协调者和某参与者都挂了之后新选举的协调者不知道当前应该提交还是回滚的问题。
新协调者来的时候发现有一个参与者处于预提交或者提交阶段,那么表明已经经过了所有参与者的确认了,所以此时执行的就是提交命令。3PC 就是通过引入预提交阶段来使得参与者之间的状态得到统一,也就是留了一个阶段让大家同步一下。
3PC 相对于 2PC 做了一定的改进:引入了参与者超时机制,并且增加了预提交阶段使得故障恢复之后协调者的决策复杂度降低,但整体的交互过程更长了,性能有所下降,并且还是会存在数据不一致问题。
2PC 和 3PC 都是数据库层面的,而 TCC 是业务层面的分布式事务。
TCC 指的是Try - Confirm - Cancel。
TCC模型还有个事务管理者的角色,用来记录TCC全局事务状态并提交或者回滚事务。

TCC 对业务的侵入较大和业务紧耦合。撤销和确认操作的执行可能需要重试,因此还需要保证操作的幂等。
幂等性:多次执行得到的结果是一致的。