了解分布式事务之前我们先看事务的特性ACID
以Mysql为例子:
Atomicity(原子性)
原子性是指一个事务是一个不可分割的工作单位,其中的操作要么都做,要么都不做;如果事务中一个sql语句执行失败,则已执行的语句也必须回滚,数据库退回到事务前的状态。
语句要么全执行,要么全不执行,是事务最核心的特性,事务本身就是以原子性来定义的;实现主要基于undo log
Consistency(一致性)
一个事务在执行前后,数据库都必须处于正确的状态,
事务追求的最终目标,一致性的实现既需要数据库层面的保障,也需要应用层面的保障
Isolation(隔离性)
多个事务并发执行时,一个事务的执行不应影响其他事务的执行。
保证事务执行尽可能不受其他事务影响;InnoDB默认的隔离级别是RR,RR的实现主要基于锁机制(包含next-key lock)、MVCC(包括数据的隐藏列、基于undo log的版本链、ReadView)
Durability(持久性)
事务处理完成后,对数据的修改就是永久的,即便系统故障也不会丢失
保证事务提交后不会因为宕机等原因导致数据丢失;实现主要基于redo log
事务隔离级别
分布式事务
2PC
2-phase-commit(二阶段提交),基于XA。将事务提交分为两个阶段,需要引入协调器
第一阶段:
准备阶段,协调器向事务参与者发送确认消息,收到后返回YES(可以提交),NO(不能提交)
第二阶段:
所有事物参与者返回YES:提交事务
任何一个参与者返回NO:回滚事务
存在的问题:
1.阻塞协议
2.单点故障,协调器发生异常导致整个分布式系统无法继续工作
3.数据一致性问题,协调器发出commit命令,一部分参与者执行失败,导致数据不一致
3PC
3-phase-commit(三阶段提交),相比于2PC增加了一个准备阶段
CanCommit 询问阶段
PreCommit 准备阶段
DoCommit 提交阶段
TCC
Try阶段是做业务检查(一致性)及资源预留(隔离),此阶段仅是一个初步操作,它和后续的/confirm/i一起才能真正构成一个完整的业务逻辑。
/confirm/i阶段是做确认提交,Try阶段所有分支事务执行成功后开始执行/confirm/i。通常情况下,采用TCC则认为/confirm/i阶段是不会出错的。即 :只要Try成功,/confirm/i一定成功。若/confirm/i阶段真的出错了,需引入重试机制或人工处理。
Cancel阶段是在业务执行错误需要回滚的状态下执行分支事务的业务取消,预留资源释放。通常情况下,采用TCC则认为Cancel阶段也是一定成功的。若Cancel阶段真的出错了,需引入重试机制或人工处理
思路:下游提供回滚方案,本地事务失败时调用下游回滚接口,同时提供补偿方案,保障回滚成功;TCC是比较经典的分布式事务解决方案,形式有很多,个人觉得劣势也是开发成本太高,需要下游协作,但是使用范围很广泛,也容易扩展;
在不需要强一致性的业务场景下,都可以通过定时任务+幂等操作来实现最终一致性。
SAGA
本地消息表



