分布式事务常见的实现方式

两阶段提交协议(2PC, Two-Phase Commit)

两阶段提交协议是最经典的分布式事务协议,主要分为两个阶段:

准备阶段(Prepare Phase):协调者向所有参与者发送准备请求,参与者执行事务并记录日志,但不提交。参与者将执行结果(准备成功或失败)返回给协调者。

提交阶段(Commit Phase):如果所有参与者都准备成功,协调者发送提交请求,参与者提交事务;如果有任何参与者准备失败,协调者发送回滚请求,所有参与者回滚事务。

2PC的优点是实现简单且具有强一致性,缺点是存在协调者单点故障问题,在准备阶段完成后,若协调者宕机,会导致参与者永久阻塞。且在网络分区或节点故障时可能会导致参与者长时间锁定资源。

三阶段提交协议(3PC,Three-Phase Commit)

三阶段提交协议是对两阶段提交协议的改进,增加了一个“预提交”阶段,减少了系统阻塞时间:

准备阶段(Prepare Phase):与2PC相同,协调者向参与者发送准备请求。

预提交阶段(Pre-Commit Phase):协调者发送预提交请求,参与者收到后可以立即回复并等待最终决定。

提交阶段(Commit Phase):协调者根据所有参与者的回应,决定提交或回滚。

3PC的优点是减少了阻塞时间,但实现较为复杂。

基于消息队列的最终一致性

这种方式通过使用消息队列和补偿机制来实现最终一致性:

事务消息:在事务操作的每一步都通过消息队列通知其他服务,确保消息的可靠传递。

补偿机制:如果某一步操作失败,通过补偿机制撤销之前的操作,保证系统最终一致。

这种方式的优点是实现简单,且适用于许多实际场景,但缺点是需要设计补偿逻辑,需要消息队列支持事务消息(如RocketMQ的Half Message机制),消费者端必须实现幂等处理,可能会增加系统复杂度,且可能引入消息积压、消费延迟等问题。

Saga模式

Saga模式将长事务拆分为一系列短事务,每个短事务完成后触发下一个事务,失败时执行补偿操作:

顺序执行:每个子事务顺序执行,如果其中某个子事务失败,执行相应的补偿事务。

并行执行:多个子事务可以并行执行,所有子事务成功后事务才算成功,如果某个子事务失败,执行相应的补偿事务。

Saga模式的优点是避免了长时间锁定资源,缺点是需要设计每个子事务的补偿逻辑。

TCC(Try-Confirm-Cancel)模式

TCC模式将每个业务操作分为三个步骤:尝试(Try)、确认(Confirm)和取消(Cancel):

Try:尝试执行业务操作,预留必要的资源。

Confirm:确认执行业务操作,真正提交事务。

Cancel:取消业务操作,释放预留的资源。

TCC模式的优点是灵活性高,但实现复杂,需要设计每个步骤的逻辑,Confirm/Cancel操作必须实现幂等性,需要业务代码显式实现三阶段逻辑,侵入性较强,适合资金类等需要严格资源控制的场景。

基于数据库的分布式事务

一些现代数据库(如Google Spanner、CockroachDB等)提供了内置的分布式事务支持:

分布式锁:利用数据库的分布式锁机制,确保多个节点之间的事务一致性。

多版本并发控制(MVCC):通过多版本并发控制实现高效的事务处理。

这种方式的优点是开发简单,缺点是依赖于特定数据库的实现。