对于分布式事务,相信所有人都应该很了解,为什么会有分布式事务?无论是数据量导致的分库,还是现在微服务盛行的场景都是他出现的原因。
这一篇内容还是避免不了俗套,主要的范围无非是XA、2PC、3PC、TCC,再最后到Seata。
但是,我认为这东西,只是适用于面试和理论的了解,你真要说这些方案实际生产中有人用吗?
有,但是会实现的更简单,不会套用理论来实现,大厂有大厂的解决方案,中小公司用框架或者压根就不存在分布式事务的问题。
那,为什么还要写这个?
为了你面试八股文啊,小可爱。
事务
要说分布式事务,首先还是从事务的基本特征说起。
A原子性:在事务的执行过程中,要么全部执行成功,要么都不成功。
C一致性:事务在执行前后,不能破坏数据的完整性。一致性更多的说的是通过AID来达到目的,数据应该符合预先的定义和约束,由应用层面来保证,还有的说法是C是强行为了ACID凑出来的。
I隔离性:多个事务之间是互相隔离的,事务之间不能互相干扰,涉及到不同事务的隔离级别的问题。
D持久性:一旦事务提交,数据库中数据的状态就应该是永久性的。
XA
XA(eXtended Architecture)是指由X/Open 组织提出的分布式事务处理的规范,他是一个规范或者说是协议,定义了事务管理器TM(Transaction Manager),资源管理器RM(Resource Manager),和应用程序。
事务管理器TM就是事务的协调者,资源管理器RM可以认为就是一个数据库。
2PC
XA定义了规范,那么2PC和3PC就是他的具体实现方式。
2PC叫做二阶段提交,分为投票阶段和执行阶段两个阶段。
投票阶段
TM向所有的参与者发送prepare请求,询问是否可以执行事务,等待各个参与者的响应。
这个阶段可以认为只是执行了事务的SQL语句,但是还没有提交。
如果都执行成功了就返回YES,否则返回NO。
执行阶段
执行阶段就是真正的事务提交的阶段,但是要考虑到失败的情况。
如果所有的参与者都返回YES,那么就执行发送commit命令,参与者收到之后执行提交事务。
反之,只要有任意一个参与者返回的是NO的话,就发送rollback命令,然后执行回滚的操作。
2PC的缺陷
同步阻塞,可以看到,在执行事务的过程当中,所有数据库的资源都被锁定,如果这时候有其他人来访问这些资源,将会被阻塞,这是一个很大的性能问题。
TM单点问题,只要一个TM,一旦TM宕机,那么整个流程无法继续完成。
数据不一致,如果在执行阶段,参与者脑裂或者其他故障导致没有收到commit请求,部分提交事务,部分未提交,那么数据不一致的问题就产生了。
3PC
既然2PC有这么多问题,所以就衍生出了3PC的概念,也叫做三阶段提交,他把整个流程分成了CanCommit、PreCommit、DoCommit三个步骤,相比2PC,增加的就是CanCommit阶段。
CanCommit
这个阶段就是先询问数据库是否执行事务,发送一个canCommit的请求去询问,如果可以的话就返回YES,反之返回NO。
PreCommit
这个阶段就等同于2PC的投票阶段了,发送preCommit命令,然后去执行SQL事务,成功就返回YES,反之返回NO。