通过阅读 Seata中的四种不同的事务模式原理和应用场景_seata默认-CSDN博客所做笔记
Seata
事务协调者充当接待人员,领事务参与者入门;事务管理器分配资源管理器执行相应工作,资源管理器完成相应工作后提交给事务管理器完成事务提交或回滚
Seata提供四种不同的分布式事务解决方案
XA模式:强一致性分阶段事务模式,牺牲了一定的可用性,无业务侵入
AT模式:最终一致的分阶段事务模式,无业务侵入 (Seata的默认模式)
TCC模式:最终一致的分阶段事务模式,有业务侵入
SAGA模式:长事务模式,有业务侵入
本地锁和全局锁
XA模式
两阶段提交
一阶段
事务协调者通知每个事物参与者执行本地事务
本地事务执行完成后报告事务执行状态给事务协调者,此时事务不提交,继续持有本地锁
二阶段
事务协调者基于一阶段的报告来判断下一步操作:
如果一阶段都成功,则通知所有事务参与者,提交事务
如果一阶段任意一个参与者失败,则通知所有事务参与者回滚事务
优缺点
优点
- 事务的强一致性,满足ACID原则
- 常用数据库都支持,实现简单,并且没有代码侵入
缺点
- 因为一阶段需要锁定数据库资源,等待二阶段结束才释放,性能较差(整个阶段都持有锁)
- 依赖关系型数据库实现事务
AT模式
用户只需关注自己的“业务 SQL”,用户的 “业务 SQL” 作为一阶段,Seata 框架会自动生成事务的二阶段提交和回滚操作 (通过本地锁和UNDO LOG实现)
阶段一RM的工作:
- 注册分支事务
- 记录undo-log(数据快照)
- 执行业务sql并提交
- 报告事务状态
阶段二提交时RM的工作:
- 删除undo-log即可
阶段二回滚时RM的工作:
- 根据undo-log恢复数据到更新前
案例演示
AT与XA的区别
- XA模式一阶段不提交事务,锁定资源;AT模式一阶段直接提交,释放本地锁,不锁定资源。
- XA模式依赖数据库机制实现回滚;AT模式利用数据快照实现数据回滚。
- XA模式强一致;AT模式最终一致
脏写问题
在多线程并发访问AT模式的分布式事务时,有可能出现脏写问题
二阶段如果是回滚的话,Seata 就需要回滚一阶段已经执行的“业务 SQL”,还原业务数据。回滚方式便是用“before image”还原业务数据;但在还原前要首先要校验脏写,对比“数据库当前业务数据”和 “after image”,如果两份数据完全一致就说明没有脏写,可以还原业务数据,如果不一致就说明有脏写
解决思路:
引入了全局锁的概念(对整个分布式数据库实例加锁,整个数据库就处于只读状态)。在释放行锁之前,先拿到全局锁。避免同一时刻有另外一个事务来操作当前数据。
优缺点
AT模式的优点:
- 一阶段完成直接提交事务,释放数据库资源,性能比较好
- 利用全局锁实现读写隔离
- 没有代码侵入,框架自动完成回滚和提交
AT模式的缺点:
- 两阶段之间属于软状态,属于最终一致
- 框架的快照功能会影响性能,但比XA模式要好很多
TCC模式
TCC模式与AT模式非常相似,每阶段都是独立事务,不同的是TCC通过人工编码来实现数据恢复
流程分析
优缺点
优点
- 一阶段完成直接提交事务,释放数据库资源,性能好
- 相比AT模型,无需生成快照,无需使用全局锁,性能最强
- 不依赖数据库事务,而是依赖补偿操作,可以用于非事务型数据库
缺点
- 有代码侵入,需要人为编写try、Confirm和Cancel接口,太麻烦
- 软状态,事务是最终一致
- 需要考虑Confirm和Cancel的失败情况,做好幂等处理
SAGA模式
在 Saga 模式下,分布式事务内有多个参与者,每一个参与者都是一个冲正补偿服务,需要用户根据业务场景实现其正向操作和逆向回滚操作。
分布式事务执行过程中,依次执行各参与者的正向操作,如果所有正向操作均执行成功,那么分布式事务提交。如果任何一个正向操作执行失败,那么分布式事务会去退回去执行前面各参与者的逆向回滚操作,回滚已提交的参与者,使分布式事务回到初始状态。