分布式事务快速入门
分布式事务基本概念
使用分布式事务的场景:分布式场景下的跨数据库事务
分布式事务诞生的理论:CAP和Base
3种一致性:
强一致性 :系统写入了什么,读出来的就是什么。
弱一致性 :不一定可以读取到最新写入的值,也不保证多少时间之后读取到的数据是最新的,只是会尽量保证某个时刻达到数据一致的状态。
最终一致性 :弱一致性的升级版。系统会保证在一定时间内达到数据一致的状态
其他一致性:
读写一致性:是一种在分布式系统中保证读取操作与写入操作之间一致性的模型
柔性事务(最终一致性):TCC、 Saga、MQ 事务 、本地消息表补偿
刚性事务(强一致性):2PC,3PC
刚性事务是基于数据库层面保证事务的强一致性的,柔性事务是基于外部中间件或者代码保证事务的最终一致性的
业务代码侵入方案:TCC,Saga
业务代码无侵入方案:2PC,3PC
XA规范的角色:
Application Program :AP,应用程序本身
Resource Manager : RM,资源管理器,指的是数据库
Transational Manager :TM,事务管理器
2PC-两阶段提交
2PC的执行流程:
分为准备阶段和提交阶段
准备阶段:询问RM是否能执行事务,如果能执行事务就直接做预处理,例如Mysql的预处理就是写入Undo日志和Redo日志,但是不写入Binlog日志,因为此时事务还没提交
提交阶段:查看所有的RM是否预处理成功(全部RM属于就绪状态),如果全部成功就提交,如果有一个失败了就回滚
2PC的优缺点:
优点:
- 简单
- 数据强一致性
缺点:
- 同步阻塞,要等待所有事务都就绪再提交
- 部分数据不一致情况,commit和rollback不能保证所有节点同时成功
- 没有超时机制,TM挂掉后多个RM的事务会一直等待提交
3PC-三阶段提交
3PC的执行流程:
准备阶段,预提交阶段,提交阶段
准备阶段:询问RM是否能执行事务,超时或者RM说不能执行事务就中断事务
预提交阶段:再一次询问RM是否能执行事务,如果可以就进入预提交(写入Undo日志和Redo日志),如果No或者超时就回滚
提交阶段:所有RM都预处理成功,则提交事务。有一个RM失败或者超时了,则回滚
2PC对比3PC:
- 3PC是多次判断数据库状态(多了一次判断),加入了新的协议,同时增加了通信的开销
- 3PC引入的RM超时机制是多次一举的,其实2PC就够了,2PC的RM一直等待的情况其实是理论而已,实际Mysql等数据库本身就有事务超时机制
- 2PC实现更加简单
- 3PC不仅没有完全解决阻塞问题还会导致性能更糟糕,多数应用会选择通过复制状态机解决 2PC 的阻塞问题
TCC补偿事务
TCC的执行流程:
Try,Confirm,Cancel
执行流程:Try,Try成功就Confirm,失败就Cancel
TCC会将日志记录,实战中会实现Confirm失败和Cancel失败的情况,会进行重试,如果重试多次失败要走人工补偿
TCC和2PC的区别:
- TCC是基于代码自定义逻辑来补偿保证最终一致性,2PC是基于Mysql事务保证强一致性
- TCC的Try是类似于冻结,例如500元转账100元是冻结这个100元而不是真的转账。而2PC是给这500元的记录上记录锁
- 业务补偿逻辑的区别,TCC不是基于数据库的通用事务机制,而是根据具体业务的流程和规则编写的代码
TCC和2PC,3PC的区别:
- 2PC/3PC 依靠数据库或者存储资源层面的事务,TCC 主要通过修改业务代码来实现。
- 2PC/3PC 属于业务代码无侵入的,TCC 对业务代码有侵入。
- 2PC/3PC 追求的是强一致性,在两阶段提交的整个过程中,一直会持有数据库的锁。TCC 追求的是最终一致性,不会一直持有各个业务资源的锁
MQ事务
RocketMQ和Kafka都提供了事务的相关功能
可以将生产消息,消费,处理整个过程变成一个原子性的操作
Saga事务
长事务分为多个短事务,然后短事务分别按顺序提交,有一个短事务失败就回滚
失败的补偿逻辑还是要通过业务代码补偿
正向补偿的执行顺序(失败回滚):T1,T2,…,Ti(失败),Ci(补偿),…,C2,C1
反向补偿的执行顺序(失败重试):T1,T2,…,Ti(失败),Ti(重试)…,Ti+1,…,Tn。