什么是分布式事务
分布式事务就是在分布式系统中实现事务功能的操作,它是由多个本地事务组成的一个大事务。
事务特性
我们知道事务有4个非常重要的特性,即我们常说的(ACID)。
-
Atomicity(原子性):
是说事务是一个不可分割的整体,所有操作要么全做,要么全不做;只要事务中有一个操作出错,回滚到事务开始前的状态的话,那么之前已经执行的所有操作都是无效的,都应该回滚到开始前的状态。 -
Consistency(一致性):
是说事务执行前后,数据从一个状态到另一个状态必须是一致的,比如A向B转账( A、B的总金额就是一个一致性状态),不可能出现A扣了钱,B却没收到的情况发生。 -
Isolation(隔离性):
多个并发事务之间相互隔离,不能互相干扰。关于事务的隔离性,可能不是特别好理解,这里的并发事务是指两个事务操作了同一份数据的情况;而对于并发事务操作同一份数据的隔离性问题,则是要求不能出现脏读、幻读的情况,即事务A不能读取事务B还没有提交的数据,或者在事务A读取数据进行更新操作时,不允许事务B率先更新掉这条数据。而为了解决这个问题,常用的手段就是加锁了,对于数据库来说就是通过数据库的相关锁机制来保证。 -
Durablity(持久性):
事务完成后,对数据库的更改是永久保存的,不能回滚。
分布式事务实现方式
分布式事务模式 | 介绍 | 技术栈 |
---|---|---|
AT 模式 | 无侵入的分布式事务解决方案,适用于不希望对业务进行改造的场景,几乎0学习成本(sql都由框架托管统一执行,会存在脏写问题) | 理论有:二阶段、三阶段提交;框架:seata、shardingsphere |
TCC 模式 | 高性能分布式事务解决方案,适用于核心系统等对性能有很高要求的场景(第一阶段会产生行锁,事务执行太久会锁行很久) | seata、service-comb |
Saga 模式 | 长事务解决方案,适用于业务流程长且需要保证事务最终一致性的业务系统(第一阶段就操作DB,会存在脏读问题) | seata、shardingsphere、service-comb |
XA模式 | 分布式强一致性的解决方案,但性能低而使用较少。 | seata、shardingsphere |
AT模式
2PC:二阶段提交
它是添加一个事务协调者来协调多个参与者事务的提交和回滚。它有两个阶段,准备阶段和提交阶段。
- 准备阶段:协调者会向每个参与者发送命令,这一步除了提交的操作,其他操作都完成了。
- 提交阶段:协调者会同步等待所有参与者响应,根据所有参与者响应的结果,判断是提交、回滚事务。
以下几点是两阶段提交协议中会遇到的一些问题:
-
性能问题
2PC是同步阻塞的过程,如果一个参与者响应比较慢,其他就要长时间占用资源。效率低。 -
协调者单点故障问题
事务协调者是整个XA模型的核心,一旦事务协调者节点挂掉,会导致参与者收不到提交或回滚的通知,从而导致参与者节点始终处于事务无法完成的中间状态。要引入多个协调者,防止协调者的单点故障问题。增加了故障切换等复杂度。 -
丢失消息导致的数据不一致问题
在第二个阶段,如果发生局部网络问题,一部分事务参与者收到了提交消息,另一部分事务参与者没收到提交消息,那么就会导致节点间数据的不一致问题。
既然两阶段提交有以上问题,那么有没有其他的方案来解决呢?
3PC:三阶段提交
三阶段提交,是为了解决2PC直接锁定资源的问题,它比2PC多一个预提交阶段,并且参与者引入了超时机制。
- 准备阶段:这一阶段只是询问参与者是否可以执行事务。
- 预提交阶段:和2PC的准备阶段一样。
- 提交阶段:和2PC的提交阶段一样。
具体流程图如下:
相对于2PC的优点
- 增加了超时机制:一旦事务参与者迟迟没有收到协调者的Commit请求,就会自动进行本地commit,这样相对有效地解决了协调者单点故障的问题。
存在的问题:
- 性能问题:增加了一个阶段,交互流程变长,性能下降。
- 数据不一致问题:如果参与者等待提交超时,导致事务提交,但是实际应该回滚,会导致数据不一致。
TCC模式
2PC 和 3PC 都是数据库层面的,而 TCC 是业务层面的分布式事务,就像我前面说的分布式事务不仅仅包括数据库的操作,还包括发送短信等,这时候 TCC 就派上用场了!
TCC 指的是Try - Confirm - Cancel
- Try 指的是预留,即资源的预留和锁定,注意是预留。
- Confirm 指的是确认操作,这一步其实就是真正的执行了。
- Cancel 指的是撤销操作,可以理解为把预留阶段的动作撤销了。
其实从思想上看和 2PC 差不多,都是先试探性的执行,如果都可以那就真正的执行,如果不行就回滚。
比如说一个事务要执行A、B、C三个操作,那么先对三个操作执行预留动作。如果都预留成功了那么就执行确认操作,如果有一个预留失败那就都执行撤销动作。
下图为TCC模型中各个角色的执行流程:
TCC存在的问题:
- 侵入性问题:每个事物都要在业务上定义三个动作,所以对业务的侵入性和业务紧耦合。
- 保证幂等性:提交和确认操作,可能会被重试,所以要保证幂等性。
Saga模式
Saga 是一种补偿协议,在 Saga 模式下,分布式事务内有多个参与者,每一个参与者都是一个冲正补偿服务,需要用户根据业务场景实现其正向操作和逆向回滚操作。
XA模式
因为XA模式是 分布式强一致性的解决方案,并且性能太低而使用较少。