分布式事务是什么
分布式事务就和名字一样是在分布式的情况下需要考虑的。
一、MySQL的事务
把多条语句作为一个整体进行操作的功能,被称为数据库事务。数据库事务可以确保该事务范围内的所有操作都可以全部成功或者全部失败。
MySQL事务支持ACID,原子性,持久性,一致性,隔离行四个特性,其中原子性能保证事务内所有执行都完整完成,不存在部分完成的情况,一致性指事务执行前后不会改变数据库的状态,持久性指能够一直保存(简单地说就是保存在磁盘上不会丢,除非你把磁盘烧了),隔离性指每个事务之间不会相互影响。
二、分布式理论
2.1 CAP理论
C(一致性)指的是分布式系统中从多副本读取数据时的一致性。分强一致性、弱一致性和最终一致性。
A(可用性)保证每个请求不管成功或者失败都有响应。
P(分区容错性)分区容忍性是分布式系统中必须实现的(高可用),一个节点挂了不能导致服务也挂了。
不存在CAP都满足的,最多CP+HA 高可用。
2.2 BASE理论
Basically Available(基本可用)
Soft state(软状态)
Eventually consistent(最终一致性)
三、分布式事务
分布式事务指事务的发起者、资源及资源管理器和事务协调者分别位于分布式系统的不同节点之上(同时写、修改多个数据库),微服务里面是一个操作需要同时修改不同服务内的数据,例如一个订单的微服务在创建时需要减掉相应商品的库存,这时候如果先创建订单,然后再减掉商品库存就会导致常见的超卖现象。还有一种情况可能是,订单创建了,商品这个微服务挂了,然后库存没减掉。这些现象在分布式的情况中需要注意。
3.1 两阶段提交/XA
XA是由X/Open组织提出的分布式事务的规范,XA规范主要定义了(全局)事务管理器(TM)和(局部)资源管理器(RM)之间的接口。本地的数据库如mysql在XA中扮演的是RM角色
xa start 'xxx'
CRUD
xa end 'xxx'
xa prepare 'xxx' # 如果这个数据库和全局事务管理器断开了就会自动回滚
xa commit 'xxx' # 所有参与者都完成了prepare,就进入提交
图片来源DTM(https://dtm.pub/)
XA一共分为两个阶段:
第一阶段准备:所有的参与者RM准备执行事务并锁住需要的资源。参与者ready时,向TM报告已准备就绪。
第二阶段(commit/rollback):当TM确认所有参与RM都ready后,向所有参与RM发送commit命令。
XA事务的特点是:
- 简单易理解,开发较容易。
- 对资源进行长时间的锁定,影响系统的并发。
3.2 SAGA
核心思想是将长事务拆分为多个本地事务,由Saga事务协调器协调,如果正常结束那就正常完成,如果某个步骤失败,则根据相反顺序一次调用补偿操作(类似undo log)

图片来源DTM(https://dtm.pub/)
Saga事务的特点:
- 并发度高,不用像XA事务一样长时间锁住资源。
- 需要定义正常操作以及补偿操作,开发量更大了(写undo log,double的业务逻辑)。
- 一致性较弱,对于转账,可能发生用户A已扣款,最后转账又失败的情况。
3.3 TCC
TCC(Try-Confirm-Cancel),TCC分为3个阶段:
- Try阶段:尝试执行,完成所有业务检查(一致性),预留必须的业务资源(准隔离性)。
- Confirm阶段:确认执行真正执行业务,不作任何业务检查,只是用Try阶段预留的业务资源,Confirm操作要求具备幂等设计,Confirm失败后需要进行重试。
- Cancel阶段:取消执行,释放Try阶段预留的业务资源。Cancel阶段的异常和Confirm阶段异常处理方案基本一致,要求满足幂等设计。

TCC的Confirm/Cancel阶段在业务逻辑上是不允许返回失败的,如果因为网络或者其他临时故障,导致不能返回成功,TM会不断的重试,直到Confirm/Cancel返回成功。
TCC特点如下:
- 并发度高,无长期资源锁定。
- 开发量较大,需要提供Try、Confirm、Cancel接口。
- 一致性较好,不会发生SAGA已扣款最后有家转账失败的情况。
- TCC适用于订单类业务,对中间状态有约束的业务。
3.4 本地消息表

图片来源DTM(https://dtm.pub/)
写本地消息和业务操作放在一个事务里,保证了业务和发消息的原子性,要么他们全都成功,要么全都失败。
容错机制:
- 扣减余额失败时,事务直接回滚,无后续步骤。
- 轮询生成消息失败,增加余额事务失败都会进行重试。
本地消息表的特点:
- 长事务仅需分成多个任务,使用简单。
- 生产者需要额外的创建消息表。
- 不支持回滚。
- 轮询生产消息难实现,如果定时轮询会延长事务总时长,如果订阅binlog则开发维护困难。
3.5 事务消息
事务消息发送及提交:
- 发送消息(half消息)。
- 服务端存储消息,并响应消息写入结果。
- 根据发送结果执行本地事务(如果写入失败,此时half消息对业务不可见,本地逻辑不执行)。
- 根据本地事务状态执行Commit或者Rollback(Commit操作发布消息,消息对消费者可见)。
3.6 最大努力通知
最大努力通知适用于业务通知类型,例如微信交易的结果,就是通过最大努力通知方式通知各个商户,既有回调通知,也有交易查询接口。
3.7 AT事务模型
优点是该事务模式使用方式,类似XA模式,业务无需编写各类补偿操作,回滚由框架自动完成,该模式缺点也较多,一方面类似XA,存在较长时间的锁,不满足高并发的场景;另一方面存在脏回滚之类的问题,容易引发数据不一致。
四、分布式事务的新方案
二阶段消息(DTM)
图片来源DTM(https://dtm.pub/)