分布式_分布式事务_强事务(CP)_两阶段提交协议

一、两阶段提交协议

  第一阶段:提交请求阶段/投票阶段

    两阶段协议就是通过两次协商来完成一个事务操作。一般第一个事务的发起方叫做 协调者。其他服务叫做参与者。第一步,协调者会通知其他系统,我们要执行一个事务啦。其他系统这时会通知协调者自己是否准备好执行事务。如果都可以执行,则进入第二步。如果有一个系统说自己不能执行事务,则整个分布式事务回滚。上图:
在这里插入图片描述
    上图表示了投票阶段所有系统的操作过程,这里假设的是所有系统都是正常的情况下的流程。假设短信服务或者积分服务中的一个宕机了或者因为某某原因(也许积分服务这边也在执行某个事务,卡着等待了。)没有告知用户服务自己已经准备好,那么用户服务会认为事务发起失败,直接报错。如果是用户服务挂了,那么其他参与者就会一直等待用户服务的消息,需要自己写超时逻辑。要是都没问题,则进入第二阶段:提交执行阶段。

  第二阶段:提交执行阶段

    直接上图:
在这里插入图片描述

  1. 此时所有服务执行事务,并且用户服务统计各个系统的事务执行结果。如果所有系统都执行成功,则整个分布式事务执行成功。
  2. 如果此时用户服务(协调者)宕机,则其他服务就收不到用户服务下发的事务提交消息,就会一直卡着等待。因为二阶段提交默认只有协调者有超时时间,那么参与者需要自己写超时处理流程。
  3. 如果此时短信服务或者积分服务宕机或者操作执行失败,那么用户服务则会收到失败的消息,通知各个系统回滚事务。要是这个时候用户服务也挂了,那么其他服务也会因为没有收到用户服务的通知而自行执行自己写的超时业务代码。

二、总结

    按笔者的了解,Mysql、Oracle数据库的XA协议就是使用二阶段提交协议的。在java中,用Mysql举例,你可以使用MysqlXAConnection来操作。但是这样使用的话,是要在一个项目中访问多个数据库,这是违反微服务开发规范的。而且在微服务开发中,基本上是一个微服务对应一个数据库,那么数据库自带的这种方案也使用不了。
    而且二阶段提交(XA协议)也会存在以下问题:

  1. 在投票阶段,需要锁定你操作的数据,其他人就不能操作了。这样明显就会拉低效率。
  2. 数据有可能是存在不同的库表中的,这样就直接GG了。
  3. 如果协调者挂了,其他参与者就会一直等着,这样就很尴尬了。

    貌似实际生产中好像也没人用二阶段提交吧~~欢迎讨论

猜你喜欢

转载自blog.csdn.net/qq_30752451/article/details/106715775