springcloudalibaba架构(28):分布式事务解决方案

文章目录

  • 前言
  • 第一节 分布式事务基础
    • 1. 事务
    • 2. 本地事务
    • 3. 分布式事务
    • 4. 分布式事务的场景
  • 第二节 分布式事务解决方案
    • 1. 全局事务(2PC)
    • 2. 可靠消息服务(MQ事务消息)
    • 3. 本地消息表(最大努力通知)
    • 4. 补偿事务(TCC)
  • 传送门

前言

什么是分布式事务?它于本地事务有什么区别?如何解决分布式事务的问题?

第一节 分布式事务基础

1. 事务

事务指的就是一个操作单元,在这个操作单元中的所有操作最终要保持一致的行为,要么同时成功,要么同时被撤销。

2. 本地事务

本地事务其实可以认为是数据库提供的事务机制。说到数据库事务就不得不说,数据库事务中的四大特性:

  • A: 原子性,一个事务中的所有操作,要么全部完成,要么全部不完成
  • C: 一致性,在一个事务执行前和执行之后数据库都必须处于一致性状态
  • I : 隔离性,在并发环境中,当不同的事务同时操纵相同的数据时,事务之间互不影响。
  • D:持久性,指的是只要事务成功结束,它对数据库的所有更新都必须被永久的保存下来。
    数据库事务在实现时会将一次事务设计的所有操作全部纳入到一个不可分割的执行单元,该执行单元中的所有操作要么都成功,要么都失败,只要其中任一操作执行失败,都会导致整个事务的回滚。

3. 分布式事务

      分布式事务指事物的参与者、支持事务的服务器、资源服务器以及事务管理器分别位于不同的分布式系统的不同节点之上。
      简单的说,就是一次大的操作由不同的小操作组成,这些小的操作分布在不同的服务器上,且属于不同的应用,分布式事务需要保证这些小操作要么全部成功,要么全部失败。
本质上,分布式事务就是为了保证不同数据库的数据一致性。

4. 分布式事务的场景

分布式事务大体分为以下几种方式

  • 单微服务多库
    springcloudalibaba架构(28):分布式事务解决方案_第1张图片

  • 多微服务单库
    springcloudalibaba架构(28):分布式事务解决方案_第2张图片

  • 多微服务多库
    springcloudalibaba架构(28):分布式事务解决方案_第3张图片

第二节 分布式事务解决方案

1. 全局事务(2PC)

全局事务基于DTP模型实现。DTP是由X/Open组织提出的一种分布式事务模型–X/Open Distributed Transaction Processing Reference Model。它规定了要实现分布式事务,需要三种角色:

  • AP:Application应用系统(微服务)
  • TM:Transaction Manager事务管理器(全局事务管理器)
  • RM:Resource Manager资源管理器(数据库)
    整个事务分为两个阶段:
  • 阶段一:表决阶段,所有参与者都将参与本事务执行预提交,并将能够成功的信息反馈给协调者
  • 阶段二:执行阶段,协调者根据所有参与者的反馈,通知所有参与者,步调一致地执行提交和回滚。
    springcloudalibaba架构(28):分布式事务解决方案_第4张图片
    springcloudalibaba架构(28):分布式事务解决方案_第5张图片
    优点
  • 提高了数据一致性的概率,实现成本低
    缺点
  • 单机问题: 事务协调者宕机
  • 同步阻塞:延迟了提交时间,加长了资源阻塞
  • 数据不一致问题:提交的第二阶段,依然存在commit结果未知的问题,可能导致数据不一致。

2. 可靠消息服务(MQ事务消息)

基于可靠消息服务的方案是通过消息中间件保证上、下游应用数据操作的一致性。假设A和B系统,分别处理任务A和任务,此时存在一个业务流程,需要将任务A和任务B在同一个事务中处理。就可以使用消息中间件来实现分布式事务。
springcloudalibaba架构(28):分布式事务解决方案_第6张图片
RocketMQ消息中间件事务消息,请见springcloudalibaba架构(25):RocketMQ事务消息

1.发送半事务消息到消息中间件,利用半实物消息实现A任务的的事务处理
2. 消息由中间件发送到系统B,系统B根据投递过来的消息进行处理,返回给消息中间件。

  • 如果消息中间件收到确认应答后便认为该事务处理完毕
  • 如果消息中间件在等待确认应答超时之后就会重新投递,直到下游消费者返回消费成功响应为止。一般消息中间件可以设置消息重试次数和时间间隔,如果最终还是不能成功投递,则需要手动干预。这里之所以使用人工干预,而不是使用让A系统回滚,主要是考虑到整个系统设计的复杂度问题。
    基于可靠消息服务的分布式事务,前半部分使用异步,注意性能;后半部分使用同步,注意开发成本。

MQ事务消息的缺点是实现难度很大,主流MQ不支持,比如RabbitMQ和Kafka 不支持事务消息。

3. 本地消息表(最大努力通知)

本地消息表的方案最初是由eBay提出,核心思路是将分布式事务拆分成本地事务进行处理。
最大努力通知也被称为定期校对,其实是对第二种解决方案的进一步优化。它引入了本地消息表来记录错误消息,然后加入失败消息的定期校对功能,来进一步保证消息会被下游系统消费。
springcloudalibaba架构(28):分布式事务解决方案_第7张图片
第一步 消息由A系统投递到消息中间件

  1. 处理业务的同一事务中,向本地消息表写入一条记录
  2. 准备专门的消息发送者不断地发送本地消息表中的消息到消息中间件,如果发送失败则重试

第二步 消息由中间件投递到系统B

  1. 消息中间件收到消息后负责将该消息同步投递到响应的下游系统,并触发下游系统的任务执行
  2. 当下游系统处理成功后,向消息中间件反馈确认应答,消息中间件便可以将该消息删除,从而该事务完成
  3. 对于投递失败的消息,利用重试机制进行重试,对于重试失败的,写入错误消息表
  4. 消息中间需要对提供失败消息的查询接口,下游系统会定期查询失败消息,并将其消费
    优点:一种非常经典的实现,实现了最终一致性
    缺点:消息表会耦合到业务系统中,如果没封装好的解决方案,会由很多杂活要处理。

4. 补偿事务(TCC)

TCC即为Try Confirm Cancel,它属于补偿型分布式事务。TCC实现分布式事务一共有三个步骤:

  • Try 尝试待执行的业务
    这个过程并未执行业务,只是完成所有业务的一致性检查,并预留好执行所需的全部资源
  • Confirm 确认执行业务
    确认执行业务操作,不做任何业务检查,只使用Try阶段预留的业务资源。通常情况下,采用TCC则认为Confirm阶段是不会出错的。即: 只要Try成功,Confirm一定成功。若Confirm阶段真的出错了,需要引入重试机制或者人工处理。
  • Cancel:取消待执行的业务
    取消Try 阶段预留的业务资源。通常情况下,采用TCC则认为Cancel阶段一定成功的。若Cancel阶段真的出错了,需要引入重试机制或人工处理。
    springcloudalibaba架构(28):分布式事务解决方案_第8张图片
    springcloudalibaba架构(28):分布式事务解决方案_第9张图片

TCC两阶段提交于XA两阶段提交的区别是:
XA是资源层面侧分布式事务,强一致性,在两阶段提交的整个过程中,一致持有资源的锁。
TCC是业务层面的分布式事务,最终一致性,不会一直持有资源的锁。

TCC事务的优缺点
优点

  • 把数据库层的两个阶段提到了应用层来实现,规避了数据库的2PC性能低下的问题。
    缺点
  • TCC是Try、Confirm、Cancel操作功能需业务提供,开发成本高。

传送门

springcloudalibaba架构(29): Seata分布式事务(AT模式)
springcloudalibaba架构(25):RocketMQ事务消息

你可能感兴趣的:(seata,分布式,架构,数据库)