分布式一致性算法09:2PC3PC

一、两阶段提交2PC(Two-Phase Commit)
1、概述
顾名思义,两阶段提交,就是分布式数据库系统,把事务的提交过程,分为两个阶段进行操作,从而保持数据的一致性。

2、流程
a、准备阶段(Prepare Phase)
协调者(Coordinator)收到事务请求。
协调者向所有参与者(Participants)发送准备事务提交的请求。
参与者收到准备请求后,会检查本地事务的状态,判断能否完成此事务请求,并将检查结果反馈给协调者。
如果可以完成请求,参与者需要确保所有操作都已完成,事务处于可以提交、可以回滚的状态。

b、提交阶段(Commit Phase):
协调者根据所有参与者的反馈结果,决定是否提交事务。
如果任何一个参与者不同意提交,则协调者向所有参与者发送回滚请求,全部参与者进行事务回滚,事务失败。
如果所有参与者都同意提交,则协调者向所有参与者发送提交请求,全部参与者进行事务提交,事务成功。

3、示例
假设我们有一个分布式数据库系统,包含两个数据库实例A和B,以及一个协调者C。

a、准备阶段:
客户端向协调者C发送事务请求。
协调者C向数据库A和B发送准备提交的请求。
数据库A和B检查本地事务状态,判断事务可以提交,确认所有操作已完成,并将结果反馈给协调者C。

b、提交阶段:
数据库A和B都反馈可以提交,协调者C向数据库A和B发送提交请求。
数据库A和B执行提交操作,更新数据并持久化。

二、三阶段提交3PC(Three-Phase Commit)
1、概述
顾名思义,三阶段提交就是分布式数据库系统,把事务的提交过程,分为三个阶段进行操作,可以解决两阶段提交协议2PC的阻塞问题。

2、流程
a、CanCommit阶段
协调者(Coordinator)收到事务请求。
协调者向所有参与者发送一个“CanCommit”请求。
参与者收到请求后,会根据本地状态,判断是否可以完成此事务,并将判断结果反馈给协调者。
如果参与者判断可以支持事务,则返回“就绪”(Ready);否则,则返回“中止”(Abort)。

b、PreCommit阶段
协调者收到所有参与者的确认消息后。
如果所有参与者都返回“就绪”(Ready),则协调者会向所有参与者发送“PreCommit”请求。
参与者收到请求后,会锁定其资源以防止其他事务干扰,需要确保所有操作都已完成,事务处于可以提交、可以回滚的状态,并返回确认消息给协调者。

如果任何一个参与者不同意提交,则协调者向所有参与者发送取消请求,事务失败。

c、DoCommit阶段
协调者收到所有参与者的确认消息后,如果所有参与者都表示准备好提交事务,则协调者会向所有参与者发送“DoCommit”请求。
参与者收到请求后,会真正提交事务,并返回确认消息给协调者。
协调者收到所有参与者的确认消息后,事务成功。

如果任何一个参与者不同意提交,则协调者向所有参与者发送回滚请求,全部参与者进行事务回滚,事务失败。

3、示例
假设我们有一个分布式数据库系统,包含两个数据库实例A和B,以及一个协调者C。

a、CanCommit阶段
协调者C收到事务请求。
协调者C向所有参与者发送一个“CanCommit”请求。
A判断可以支持事务,返回“就绪”(Ready)。
B判断可以支持事务,返回“就绪”(Ready)。

b、PreCommit阶段
参与者A和B都向协调者C反馈“就绪”,协调者C判断可以进行下一阶段。
C向A和B发送“PreCommit”请求。
A和B收到消息后,锁定资源,让事务处于可以提交、可以回滚的状态,并返回确认消息给协调者。

c、DoCommit阶段
协调者C收到所有参与者的确认消息。
C向参与者A和B发送“DoCommit”请求。
参与者A,提交事务,向C返回提交成功。
参与者B,提交事务,向C返回提交成功。
C收到所有参与者的提交成功消息后,事务完成。

三、事务补偿TCC(Try Confirm Cancel)
1、概述
在高并发场景下,2PC和3PC的效率根本无法满足要求,于是大家就考虑如何在应用层进行优化,而不要把压力都给到数据库呢,于是TCC应运而生。
TCC可以跨数据库类型、跨系统类型操作,而且灵活性强,效率高。
但TCC需要大量业务代码的改造,各服务需要实现Try、Confirm和Cancel接口,而且要求接口必须支持幂等操作,是一种入侵性比较强的一致性实现方式。

2、流程
TCC通常会将一个大的事务,拆分为多个子事务,并将事务的提交拆分为三个阶段:Try、Confirm 和 Cancel。
这里要注意,对于非严格一致的场景,可以通过MQ等方法异步解决问题,不要加入TCC。TCC应该只涉及到强一致性的各个服务。

a、Try阶段
在Try阶段,系统会进行业务检查,并预留资源。
比如:检查用户余额、检查库存,并暂时冻结资源。

b、Confirm阶段
确认所有业务服务的操作。
比如:扣余额,扣库存。

c、Cancel阶段
如果在Try或Confirm阶段有任何问题导致事务需要回滚,系统会执行Cancel阶段,释放之前预留的所有资源。
比如:释放余额、释放库存等。

3、示例
有一个电商平台,用户想要购买一个商品,这笔交易涉及到以下几个子业务:
用户账户扣款:需要确保账户余额足够,并能正确扣款。
库存服务扣减库存:确保商品库存足够,并能正确扣库存。
订单服务创建订单:记录交易的详细信息,并能设置为正确的状态。

a、Try阶段
客户下单,事务协调器(Transaction Coordinator)指示每个服务进行Try操作:
账户服务尝试扣款,但只是冻结资金,不会实际扣除。
库存服务标记商品库存为预留状态,不会实际减少库存。
订单服务准备创建订单,但不会实际创建。

b、Confirm阶段
如果事务协调器(Transaction Coordinator)收到所有Try操作都成功的消息,确认它们的操作:
账户服务将冻结的资金实际扣减。
库存服务将预留的库存实际扣减。
订单服务实际创建订单,并标记为已完成支付。
事务协调器(Transaction Coordinator)收到全部操作成功消息,此时可判断事务成功。

c、Cancel阶段
如果Try或Confirm的任意操作失败,事务协调器将指示每个服务撤销它们的操作:
账户服务将冻结的资金解冻。
库存服务将预留的库存重新释放。
订单服务放弃创建订单。
事务协调器(Transaction Coordinator)同时会判断,事务失败,并监督完成全部业务补偿操作。

Leave a Reply

Your email address will not be published. Required fields are marked *

*