分布式事务之2PC

2PC又称两阶段提交协议
2PC是一个非常经典的强一致、中心化的原子提交协议

它执行过程中需要协调者、参与者两种角色,一个协调者中心化节点,N个参与者节点共同合作完成分布式事务操作。

下面以一个订单支付的场景案例进行对2PC协议的解析。

支付成功后,需要修改订单状态为支付完成,否则修改状态为支付失败。

2PC协议主要分为两个阶段:投票阶段、提交/执行阶段

第一阶段:投票

  1. 首先协调者收到请求后向参与者(订单服务)和参与者(支付服务)发出prepare预处理指令,通知它们进入2PC处理逻辑,并等待它们的响应。
  2. 订单服务修改订单状态为支付完成,但不commit,支付服务开始进行支付动态,但不commit。
  3. 支付服务支付成功后向协调者返回Yes,否则返回No,订单服务修改订单状态成功后向协调者返回Yes,否则返回No。

第二阶段:提交/执行(成功)

  1. 订单服务和支付服务在上一阶段都返回Yes后,协调者会向两个参与者发送commit指令。
  2. 订单服务和支付服务收到commit指令后会执行commit操作,至此,完成了整个事务操作。

第二阶段:提交/执行(失败)

  1. 在投票阶段如果参与者有其中一个返回的是No的话,那么协调者会向两个参与者发送rollback指令,通知两个参与者都回滚。
  2. 订单服务和支付服务收到rollback指令后,都会执行rollback。

上述就是2PC协议的整体执行流程,但是也存在非常明显的缺点。

2PC缺点

  1. 性能问题
    在2PC执行的整个过程中,参与者都需要等其他参与者执行完并向协调者响应Yes或No后才能执行commit/rollback操作,在等待的过程中资源是被锁定的,只有执行完commit/rollback操作才会释放,显而易见性能是低下的。
  2. 单点问题
    a. 协调者单点
    (1)如果协调者在发送完prepare指令后宕机,则在参与者执行完相应逻辑后,回复Yes/No后,则再也无法收到协调者的指令,会一直等待,直到超时。
    (2)如果协调者在发送完commit/rollback指令后宕机,如果所有参与者都收到了commit/rollback指令影响不大,但是如果只有部分参与者收到了commit指令,那么就会导致数据不一致,如果只有部分参与者收到了rollback指令,这种情况不会导致数据不一致,因为未收到rollback指令的参与者会在等待超时后自动rollback。
    解决方案
    (1)协调者冗余,设置协调者备份,当协调者挂掉后,可启用备份协调者,原协调者记录日志,备用协调者可在原协调者宕机后,根据日志继续完成操作。
    (2)在协调者宕机后,可在参与者中重新选举一个新的协调者

        b. 参与者单点
           (1) 如果参与者在收到prepare指令后,突然宕机,那么它就无法向协调者响应Yes/No,协调者会一直等待直到超时,最后向其他参与者发送rollback指令,进行回滚。
           (2) 如果参与者在执行完相应逻辑向协调者响应Yes/No之前,与i会发生相同的现象。
           (3) 如果参与者在收到commit指令后宕机,那么就会出现数据不一致的情况,因为其他参与者收到commit指令后进行commit操作。
           (4) 如果参与者在收到rollback指令后宕机,不会出现数据不一致的情况,数据库会在事务超时后自动回滚。

 

欢迎关注公众号

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值