分布式事务 6 个技术方案

2021-03-10 From 程序之心 By 丁仪

现代大型互联网系统已经告别了单机时代,微服务、负载均衡、分布式已经成为主流。在分布式系统中,对于数据库的关键操作,也需要使用事务来保证业务结果,如银行转账、交易扣款等。单机的事务可以通过数据事务或 Spring 事务来实现,分布式系统则更复杂,涉及多机房、多数据源。

分布式事务需要满足事务的基本特性,包括原子性、一致性、隔离性、持久性。事务中的一系列操作,要么全部成功,要么全部失败。在分布式事务中,最大的挑战是一致性,要求系统中所有的数据存储保持一致。一致性满足 CAP 原则,即 Consistency(一致性)、 Availability(可用性)、Partition tolerance(分区容错性)不能同时满足。Consistency 指同一时间系统数据保持一致,Availability 指部分节点异常后能否正常提供服务,Partition tolerance 指数据不一致形成分区后能否正常提供服务

目前业界对分布式事务已形成 BASE 理论共识,即 Basically Available(基本可用),Soft State(软状态)和 Eventual Consistency(最终一致性)。BASE 理论延伸了 CAP 原则,在系统出现部分节点故障时允许损失部分可用性,允许出现中间状态,并使用一些手段保证最终数据的一致性。基于 BASE 理论设计系统,能够接受短暂时间的数据不一致,流程设计上要确保这个不一致不能影响业务

两阶段提交方案

两阶段提交就是把数据处理过程分为两个阶段。使用一个独立的事务管理器,在第一阶段(prepare)向子系统发起事务请求,询问各个子系统是否就绪,根据子系统的响应决定第二阶段(commit/rollback)是否提交事务或者回滚。如果第一阶段所有子系统都就绪,则第二阶段提交事务;如有子系统未就绪,则第二阶段所有子系统进行回滚。

两阶段提交方案最大的问题是存在阻塞和不一致风险。若事务管理器故障,将导致整个系统不可用。如果第二阶段事务管理器或子系统异常,最终结果可能无法确定。

三阶段提交方案

三阶段提交方案,是把两阶段提交方案的第一步再次细分为两步。第一阶段(CanCommit),事务管理器询问子系统是否可以执行事务,得到全部肯定答复后,在第二阶段(PreCommit)向子系统发起事务请求,然后在第三阶段(DoCommit)提交或者回滚。

TCC 方案

TCC 方案,全称是 try-confirm-cancel,各阶段含义是:

  • try:尝试执行,完成业务检查,预留业务资源;
  • confirm:执行事务,不做任何检查,使用 try 预留的资源,满足幂等性;
  • cancel:取消事务,不做任何检查,释放 try 预留的资源,满足幂等性;

本地消息表方案

假设系统 A、系统 B 是分布式事务的参与者。

使用本地消息表方案,要求系统 A 和系统 B 支持幂等,并且系统 A 能够进行回滚。

可靠消息方案

可靠消息方案通过消息队列来保证分布式事务。流程如下:

  • 系统 A 发送 prepare 消息,若失败,事务直接失败;
  • 消息发送成功后,系统 A 执行本地操作;
  • 本地操作成功后,系统 A 发送 confirm 消息,否则发送回滚消息;
  • 系统 B 定时消费消息队列中的消息;
  • 系统 B 收到 confirm 消息后,执行本地操作;
  • 系统 B 本地操作成功后,发送 ACK 消息,否则业务失败后系统 B 向 A 系统发送回滚请求
  • 消息队列定时轮询 prepare 消息,并调用系统 A 确认,若成功重发 confirm 否则回滚消息;

尽最大努力通知方案

尽最大努力通知,就是系统 A 执行成功后,发送消息,通知服务消费消息并调用系统 B,如果系统 B 执行成功则流程结束,否则会尽量调用 B 进行重试,失败到一定次数后,放弃本次事务

总结

分布式事务很难做到实时一致性,总的来说主要是保证最终一致性。在技术设计中,需要充分考虑中间状态,确保中间状态不影响业务,确保系统可用性。

本文来源:程序之心,转载请注明出处!

本文地址:https://chengxuzhixin.com/blog/article/200078.html

发表感想

© 2016 - 2022 chengxuzhixin.com All Rights Reserved.

浙ICP备2021034854号-1    浙公网安备 33011002016107号