这些年来夜晚看路灯都是有诗意的,朦朦胧胧的,眯着眼睛就会看到一条条射线,哎,随着社会的高速发展,科技的飞快进步,人的内卷,大家为了讨点生活,过着白天打电脑,晚上打电脑,做梦打电脑的生活,近视得也没什么怨言,如果眼睛不近视,那么生活也会近视,心灵也会近视!
分布式事务出现的场景那自然是分布式系统中,在传统的单体系统中,一般数据库就只有一个,所有数据表都存放在一个库中,一般涉及到事务的操作, 我们直接使用本地事务就可以,但是在分布式系统中,由于数据表可能在同一台服务器上的不同库里,也可能存在不同服务器的库里,所以就出现了分布式 事务,分布式的解决方案有多种,例如2PC,3PC,TCC等,今天主要来说一下2PC事务的思想。
2PC指的是两阶段提交,整个事务流程分为两个阶段,分别为Prepare阶段和Commit阶段,Prepare为预提交阶段,它不会提交事务,Commit阶段才是真正的提交 事务的阶段,2PC阶段我们有两个角色,一个我们叫做协调者Coordinator,它的作用就是管理参与者,一个叫做参与者Participant,它其实就是我们的服务, 如库存服务,积分服务等。
在Prepare阶段,会进行模拟执行事务,如果它能够执行这个事务,就将本地事务保存起来,但是不提交,然后给协调者返回一个能够执行的状态(我们用Yes来表示), 如果不能执行,那么就返回给协调者不能执行的状态(我们用NO来表示)。
如果在Prepare阶段所有的参与者都返回Yes,那么协调者就会给所有参与者都发送一个Commit消息,参与者收到这个Commit消息后,就会提交本地事务,然后会 释放在事务过程锁住的资源,如果Prepare阶段只要有一个参与者返回NO,那么证明事务不能执行,此时协调者就会向参与者发送Rollback消息,参与者就会回滚事务。
协调者向参与者发送Prepare消息,参与者执行完本地事务后返回协调者一个状态,表明自己是否能够执行,并将执行的事务保存起来,并没有提交。

如果所有参与者都返回Yes,则证明所有参与者都能执行这个事务,这时候事务并没有提交。

这时候协调者就给参与者发送Commit消息,告诉它们,你们可以提交你们的本地事务了,参与者收到消息后,这时候才真正的提交自己刚才执行的本地事务。

如果其中一个参与者返回NO,则证明它不能完成这个事务,此时它并不会回滚事务,而是返回不能执行的状态给协调者,告诉协调者,这个事务我无法执行。

协调者收到NO状态后,知道参与者不能执行这个事务,于是给它发送一个Rollback消息,告诉它回滚事务,参与者收到后就回滚事务。

我们从2PC的整个流程中可以看出其实会有一些问题。
当某个事务在执行的过程中,资源是会被锁住的,那么其他事务就会被阻塞,直到当前事务完成后 才轮到下一个事务执行,这在高并发的情况下显然不行,如果事务不耗时还好说,如果事务很耗时,那么就无法忍受了,不过我们得清楚一点,如果 系统中引入了分布式事务,那么效率一定会下降很多倍的。
如果协调者在发送消息后挂掉,那么参与者将会一直阻塞,因为参与者返回的状态得不到协调者的处理,所以此时就只能处于阻塞。如果参与者挂掉,那么无法 反馈消息给协调者,事务也会阻塞,不过我们可以引入一些机制来防止出现出现阻塞问题,如果参与者挂掉了,协调者那边就设置一个等待时间,比如10s还未 返回状态信息,那么就认为参与者不能执行事务,就结束本次事务,防止一直阻塞,如果协调者挂掉了,那么因为它保存了参与者返回的状态信息,所以应该对 数据进行备份,如果是高可用方案,那么其他协调者还能恢复数据继续工作,这样就不至于导致参与者收不到消息而一直阻塞,即使不是高可用方案,那么等节 点正常后也能继续处理,这样就防止了事务一直阻塞。
今天的分享就到这里,感谢你的观看,下期见。