分布式事务:
-
逻辑上的一组操作,组成这组操作的各个逻辑单元在不同的服务中,不同的服务器上,要么都成功,要么都失败。
场景。 -
场景:
不同服务,不同数据库
相同服务,不同数据库
不同服务,相同数据库 -
情况:除了本地事务的程序异常之外,网络异常、服务器宕机
-
分布式事务基础理论:
CAP:C:一致性。写完之后立马可以读取到最新数据;A:可用性。挂掉一台服务器依然可用;P:分区容忍性。分区通信失败是无法避免;
BASE:妥协的方案,本质就是一个追求AP的方案。Ba:基本可用。保证核心功能可用;S:软状态,中间状态。允许一定时间内的数据不一致;E:最终一致性。 -
没有完美的方案,强一致性和弱一致性。
-
3种解决方案:
两阶段提交2PC:2是指两个阶段,P:Prepared phrase,预提交阶段,C:Commit,提交阶段;
主流的商业数据库都已经支持了两阶段提交:XA协议,免费开源的数据库支持的还不够完善,优点是实现简单,缺点是1.开源数据库会存在支持问题2.经过多次网络传输,导致性能存在问题3.总的访问时间变长,导致总的锁定时间变长。
TCC补偿性事务:编程式解决方案。T:Try,预检资源并锁定资源;
C:Confirm,执行业务流程;C:Cancel,如果try失败则取消事务,如果confirm执行失败,要进行补偿。
MQ最终一致性
如果追求一致性:2PC,追求性能MQ最终一致性。
Seata:一站式分布式事务解决方案。默认AT模式
概念:
- 全局事务:全局事务由一系列的分支事务组成
- 分支事务:就是一个本地事务
- TC:事务协调器,负责维护全局事务的运行状态,并且可以驱动全局事务的提交或者回滚
- TM:事务管理器,负责控制全局事务的边界,开启全局事务,并且发起全局事务的提交或者回滚的决议
- RM:资源管理器,负责控制本地事务,维护本地事务的状态,接受提交或者回滚的指令,执行本地事务的提交或者回滚
Seata的执行流程、生命周期?
- TM向TC申请开启一个全局事务,全局事务开启成功并生成一个全局唯一的XID
- XID在微服务调用链路的上下文中传播
- RM向TC注册分支事务,TC把分支事务纳入XID对应全局事务的范围中
- TM向TC发起全局事物的提交或者回滚的决议
- TC协调RM执行分支事务的提交或者回滚
注意:RM在第一阶段就完成了本地事务的提交或者回滚,Seata为每个RM维护了一张undo_log表,其中保存了每一次本地事物的回滚数据,因此第二阶段回滚是依赖这张表,将数据库数据更新为这张表数据,若是二阶段提交命令,则RM并不会二次提交,而是发起一个异步请求删除undo_log中的记录。
传播行为:一个service方法调用另一个service的方法时,事务之间的影响(注意是不同service)
回滚策略:默认回滚策略:受检异常(编译时异常)都不会回滚,不受检异常都会回滚
超时事务:timeout设置超时时间。
只读事务:readOnly=true,只能操作查询
Seata的四种模式?
Seata有四种分布式事务模式,默认是AT模式,每种模式都有它的适用场景。
AT 模式是无侵入的分布式事务解决方案,适用于不希望对业务进行改造的场景,几乎0学习成本。
TCC 模式是高性能分布式事务解决方案,适用于核心系统等对性能有很高要求的场景。
Saga 模式是长事务解决方案,适用于业务流程长且需要保证事务最终一致性的业务系统,Saga 模式一阶段就会提交本地事务,无锁,长流程情况下可以保证性能,多用于渠道层、集成层业务系统。事务参与者可能是其它公司的服务或者是遗留系统的服务,无法进行改造和提供 TCC 要求的接口,也可以使用 Saga 模式。
XA模式是分布式强一致性的解决方案,但性能低而使用较少。
Seata的2PC与传统2PC区别?
架构层次方面,传统2PC方案的 RM 实际上是在数据库层,RM 本质上就是数据库自身,通过 XA 协议实现,而 Seata的 RM 是以jar包的形式作为中间件层部署在应用程序这一侧的。
两阶段提交方面,传统2PC无论第二阶段的决议是commit还是rollback,事务性资源的锁都要保持到Phase2完成才释放。而Seata的做法是在Phase1 就将本地事务提交,这样就可以省去Phase2持锁的时间,整体提高效率。