一、概述
1、什么是分布式事务?
事务是保障和数据库交互的ACID特性,分布式事务是保障在堆多个数据库进行操作的时候也能想在单机一样的效果。
2、XA协议
常见的分布式事务都是基于XA协议,这是一个分布式事务协议,该协议包括2类角色,包括事务管理器(Transaction Manager)和资源管理器(Resource Manager),又称协调者和参与者,其中事务管理器负责全局事务调度,主要负责询问资源管理器是否准备好,对其下发操作等。资源管理器负责本地数据库的提交和回滚操作。
二、两阶段提交法(2PC)
2PC模型主要包括准备阶段(prepare)和提交/回滚阶段(commit/rollback)
- 准备阶段(prepare):事务协调者先询问参与者是否准备就绪,并且将数据写入到数据库中的redo日志中,只等待commit/rollback 命令。
- 提交/回滚阶段(commit/rollback):当协调者确认所有参与者准备就绪了,就会发起commit命令,所有参与者进行commit操作,如果有参与者commit失败,则全部进行rollback。
总结:(1)所有事务在prepare阶段处于阻塞同步的状态,一直要等到所有节点准备好了才能执行commit命令;(2)在第二阶段,可能由于网络原因,导致各个节点收到的数据不一致;(3)事务管理器可能存在单点故障的问题;
三、三阶段提交法(3PC)
3PC在2PC的基础上新增一个阶段,分为:canCommit阶段–>preCommit阶段–>doCommit阶段。引入的特性包括:(1)超时机制,如果事务管理器和资源管理器通信中断,不会一直处于阻塞状态,会超时失败;(2)引入一个中间状态,降低了阻塞的粒度和失败的代价。
- canCommit阶段:和2PC一样,向参与者发送询问是否准备好了;
- preCommit阶段:这个阶段和2PC不一样,就是他会向参与者提交记录,这些记录会记录在本地节点日志中;
- doCommit阶段:协调者向参与者发送提交命令,会将数据提交,同时为避免超时阻塞的问题,参与者超时没有收到协调者命令,也会自动提交;
总结:三阶段提交法在2PC方案中插入了一个preCommit阶段,该阶段是用来确保节点状态都一致,才进行commit操作,并且该阶段的数据已经提交到本地资源管理器的日志中,在commit阶段发送命令过来即可提交。同时引入超时机制,当参与者没有收到commit命令一段时间后会自动提交,由此来保障不被阻塞或者事务管理器单点故障的问题。
2PC和3PC都是强一致性的方案,都是在数据库层面实现的。
四、事务补偿方案(TCC)
TCC的核心思路是在执行之前将资源锁定并更改执行状态,在真正执行阶段才扣除资源,在这个过程中如果扣除失败,则会进行回滚。TCC事务方案解决了事务之间的隔离性问题,一个全局事务的操作和另一个全局事务的操作不再影响。
- Try阶段:对各类资源做检测和预扣除;
- Confirm阶段:在各个服务中执行实际的操作 ;
- Cancel阶段:如果confire阶段失败,则cancel回滚 ,补偿预扣除数量;
总结:(1)重点是在try阶段会将共享资源锁定,如果失败在cancel阶段会通过回滚的方式进行补偿。(2)解决了在请求阶段所有节点阻塞的状态;
五、SAGA事务方案
核心思路是将业务分成多个小的阶段,每个阶段都有一个反向的补偿事务,在某个阶段出现问题,会将该阶段前的阶段进行反向补偿事务操作。和TCC不同的是,SAGA方式适应与流程较长的业务类型,并且业务不需要在一个原子操作内,可以异步完成整个补偿,同时对于原有业务的侵入性上没有TCC强,其可以自行在开发新的补偿操作。主要流程包括:
- 将长业务拆分成几个子的阶段,分别为T1,T2,T3…
- 为每个子阶段设计好对应的补偿操作,分别为C1,C2,C3…
六、基于MQ的分布式事务
主要思路是不同的本地事务向MQ中间件依次发送消息,MQ监听到事务执行成功则通知下游继续执行本地事务,但业务涉及的本地事务都成功执行则分布式事务完成,如果其中有失败的则MQ通知之前本地事务回滚。核心是通过MQ来监控本地事务是否执行成功。
总结:TCC和SAGA、基于MQ的方案都是柔性事务方案,都需要在业务代码中实现,有较强的侵入性。
参考资料
- 彻底掌握分布式事务2PC、3PC模型:https://www.51cto.com/article/648668.html
- TCC事务:http://icyfenix.cn/architect-perspective/general-architecture/transaction/distributed.html#tcc-%E4%BA%8B%E5%8A%A1