TCC模式
实际上类似银行卡的冻结
因为假如在A事务上提交成功 那么这个时候我并不知道最后全局是成功或者失败
这个时候我需要把该事务中操作的数据都独立到一个空间去
这样我们后面如果成功的话 就是删除这个空间的数据
如果回滚的话就是恢复空间的数据
这个空间实际上就是为了解决AT全局锁的性能影响
这里无需全局锁了
因为每个事务都有自己独立的空间 别人改不了
所以就不会出现脏读的问题了
优缺点
TCC模式的每个阶段是做什么的?
Try:资源检查和预留
Confirm:业务执行和提交
Cancel:预留资源的释放
TCC的优点是什么?
一阶段完成直接提交事务,释放数据库资源,性能好
相比AT模型,无需生成快照,无需使用全局锁,性能最强
不依赖数据库事务,而是依赖补偿操作,可以用于非事务型数据库
TCC的缺点是什么?
有代码侵入,需要人为编写try、Confirm和Cancel接口,太麻烦
软状态,事务是最终一致
需要考虑Confirm和Cancel的失败情况,做好幂等处理
理解
我觉得最大的缺点还是代码入侵的问题
代码入侵不仅可能影响到之前的代码
还可能写错逻辑 这个是最麻烦的点
事务悬挂和空回滚
1)空回滚
当某分支事务的try阶段阻塞时,可能导致全局事务超时而触发二阶段的cancel操作。在未执行try操作时先执行了cancel操作,这时cancel不能做回滚,就是空回滚。
比如我的逻辑是try的阶段冻结你的银行卡 但是我忘记冻结了 这个时候超时了 全局事务觉得回滚 那这个时候去cancel的话 都没冻结怎么解冻呢这个时候就是白忙活 空回滚
业务悬挂
对于已经空回滚的业务,之前被阻塞的try操作恢复,继续执行try,就永远不可能confirm或cancel ,事务一直处于中间状态,这就是业务悬挂。
执行try操作时,应当判断cancel是否已经执行过了,如果已经执行,应当阻止空回滚后的try操作,避免悬挂
实际上就是互相套娃 就是一定要保证顺序 先try出空间 后面的才能对空间操作
所以本质上我们需要记录现在是在try还是在哪个阶段 这个时候就会按照顺序来了
SAGA模式
Saga也分为两个阶段:
一阶段:直接提交本地事务
二阶段:成功则什么都不做;失败则通过编写补偿业务来回滚
理解
实际上就是将各个微服务中的事务分成很多部分
每一部分都是独立的 如果成功就是提交
如果有一个失败 那么类似原子性一样 大家都会回滚成初始状态
优缺点
优点:
事务参与者可以基于事件驱动实现异步调用,吞吐高
一阶段直接提交事务,无锁,性能好
不用编写TCC中的三个阶段,实现简单
缺点:
软状态持续时间不确定,时效性差
没有锁,没有事务隔离,会有脏写