# 浅析分布式事务

浅析分布式事务

一个大型业务系统往往由若干个子系统构成,这些子系统又拥有各自独立的数据库。往往一个业务流程需要由多个子系统共同完成,而且这些操作可能需要在一个事务中完成

在微服务系统中,这些业务场景是普遍存在的。此时,我们就需要在数据库之上通过某种手段,实现支持跨数据库的事务支持,这也就是大家常说的 - 分布式事务

分布式事务是由多个本地事务组成的,分布式事务跨越了多设备,之间又经历的复杂的网络,往往只能妥协到最终一致性,保证数据最终的完整性和一致性

# 1. 事务模型

描述分布式事务,常常会使用以下几个名词

  • 事务参与者:例如每个数据库就是一个事务参与者
  • 事务协调者:访问多个数据源的服务程序

一般专业的称呼如下

  • 资源管理器:Resource Manager, RM - 通常与事务参与者同义
  • 事务管理器:Transaction Manager, TM - 通常与事务协调者同义

在分布式事务模型中,一个 TM 管理多个 RM,即一个服务程序访问多个数据源;TM 是一个全局事务管理器,协调多方本地事务的进度,使其共同提交或回滚,最终达成一种全局的 ACID 特性

# 2. 2PC

2PC,Two-phase commit protocol,即两阶段提交协议,分别有协调者和参与者两个角色,整体分为两个阶段,分别是准备阶段和提交/回滚阶段

准备阶段

由事务协调者给每个参与者发送准备命令,每个参与者收到命令之后会执行相关事务操作,你可以认为除了事务的提交啥都做了,然后每个参与者会返回响应告知协调者自己是否准备成功,协调者收到每个参与者的响应之后就进入第二阶段

提交/回滚阶段

根据收集的响应,如果有一个参与者响应准备失败那么就向所有参与者发送回滚命令,反之发送提交命令

超时机制

事务协调者在第一阶段未收到个别参与者的响应,则等待一定时间就会认为事务失败,会发送回滚命令,所以在 2PC 中事务协调者有超时机制

# 2.1. 同步阻塞

可以看到在第一阶段执行了准备命令后,我们每个本地资源都处于锁定状态,因为除了事务的提交之外啥都做了

所以这时候如果本地的其他请求要访问同一个资源,比如要修改商品表 id 等于 100 的那条数据,那么此时是被阻塞住的,必须等待前面事务的完结,收到提交/回滚命令执行完释放资源后,这个请求才能得以继续

所以假设这个分布式事务涉及到很多参与者,然后有些参与者处理又特别复杂,特别慢,那么那些处理快的节点也得等着,所以说效率有点低

# 2.2. 单点故障

可以看到这个单点就是协调者,如果协调者挂了整个事务就执行不下去了

如果协调者在发送准备命令前挂了还行,毕竟每个资源都还未执行命令,那么资源是没被锁定的

可怕的是在发送完准备命令之后挂了,这时候每个本地资源都执行完处于锁定状态了,都杵着了,这就很僵硬了,如果是某个热点资源都阻塞了,就会引发一系列问题

# 2.3. 数据不一致问题

因为协调者和参与者之间的交流是经过网络的,而网络有时候就会抽风的或者发生局部网络异常

那么就有可能导致某些参与者无法收到协调者的请求,而某些收到了。比如是提交请求,然后那些收到命令的参与者就提交事务了,此时就产生了数据不一致的问题

# 2.4. 总结

2PC ,它是一个同步阻塞的强一致性两阶段提交协议

它的优势在于对业务没有侵入,可以利用数据库自身机制来进行事务的提交和回滚,也就是说提交和回滚实际操作不需要我们实现,不侵入业务逻辑由数据库完成

它的缺点是一个同步阻塞协议,会导致高延迟和性能的下降,并且存在协调者单点故障问题,极端情况下会有数据不一致的问题

当然这只是协议,具体的实现还是可以变通了,比如协调者单点问题,可以做主从来实现协调者防止单点

参考

上次更新时间: 2023-12-15 03:14:55