分布式事务
分布式事务怎么实现?
XA协议的2PC(二阶段提交)
参与者将操作成败通知协调者,再由协调者根据所有参与者的反馈情报决定各参与者是否要提交操作还是中止操作。
以开会为例
甲乙丙丁四人要组织一个会议,需要确定会议时间,不妨设甲是协调者,乙丙丁是参与者。
投票阶段
甲发邮件给乙丙丁,周二十点开会是否有时间;
丁回复有时间;
乙回复有时间;
丙迟迟不回复,此时对于这个活动,甲乙丙均处于阻塞状态,算法无法继续进行;
丙回复有时间(或者没有时间);
提交阶段
协调者甲将收集到的结果反馈给乙丙丁(什么时候反馈,以及反馈结果如何,在此例中取决
于丙的时间与决定);
乙收到;
丙收到;
丁收到;
缺点:不仅要锁住参与者的所有资源,而且要锁住协调者资源,开销大
3PC(三阶段提交)
与两阶段提交不同的是,三阶段提交有两个改动点。
1、引入超时机制。同时在协调者和参与者中都引入超时机制。
2、在第一阶段和第二阶段中插入一个准备阶段。保证了在最后提交阶段之前各参与
节点的状态是一致的。也就是说,除了引入超时机制之外,3PC把2PC的准备阶段再
次一分为二,这样三阶段提交就有CanCommit、PreCommit、DoCommit三个阶段。
阶段一:CanCommit
事务询问 执行者向所有参与者发送CanCommit请求,等待所有参与者的响应
参与者反馈响应 参与者节点若认为自身可以完成事务,返回Yes;反之,返回No
阶段二:PreCommit
若所有参与者反馈的结果都是Yes响应,那么进行事务预提交
若任意一个参与者反馈的结果是No响应,或者在等待超时之后,那么执行事务中断
阶段三:doCommit
该阶段可能存在两种情况,执行事务的提交和中断事务
若执行者接受到所有参与的Ack响应,那么执行事务提交
如果有任意一个参与者反馈No响应,或者在等待超时之后,执行中断事务
TCC(事务补偿)
TCC方案在电商、金融领域落地较多。TCC方案其实是两阶段提交的一种改进。其将整个业务逻辑的每个分支显式的分成了Try、Confirm、Cancel三个操作。
- Try 阶段主要是对业务系统做检测及资源预留,完成业务的准备工作。
- Confirm 阶段主要是对业务系统做确认提交,Try阶段执行成功并开始执行 Confirm阶段时,默认 Confirm阶段是不会出错的。即:只要Try成功,Confirm一定成功。
- Cancel 阶段主要是在业务执行错误,需要回滚的状态下执行的业务取消,预留资源释放。
基本原理如下图所示:
事务开始时,业务应用会向事务协调器注册启动事务。之后业务应用会调用所有服务的try接口,完成一阶段准备。之后事务协调器会根据try接口返回情况,决定调用confirm接口或者cancel接口。如果接口调用失败,会进行重试。
微服务倡导服务的轻量化、易部署,而TCC方案中很多事务的处理逻辑需要应用自己编码实现,复杂且开发量大。
本地消息表
本地消息表这个方案最初是 ebay 架构师 Dan Pritchett 在 2008 年发表给 ACM 的文章。设计核心是将需要分布式处理的任务通过消息的方式来异步确保执行。
大致流程如下:
写本地消息和业务操作放在一个事务里,保证了业务和发消息的原子性,要么他们全都成功,要么全都失败。
容错机制:
- 扣减余额事务 失败时,事务直接回滚,无后续步骤
- 轮序生产消息失败, 增加余额事务失败都会进行重试
本地消息表的特点:
- 长事务仅需要分拆成多个任务,使用简单
- 生产者需要额外的创建消息表
- 每个本地消息表都需要进行轮询
- 消费者的逻辑如果无法通过重试成功,那么还需要更多的机制,来回滚操作
适用于可异步执行的业务,且后续操作无需回滚的业务