Spring Cloud Alibaba(六) 分布式事务


官网:https://seata.io/

一、分布式事务基础

(一)事务

事务指的就是一个操作单元,在这个操作单元中的所有操作最终要保持一致的行为,要么所有操作都成功,要么所有的操作都被撤销。简单地说,事务提供一种“要么什么都不做,要么做全套”机制。

(二)本地事务

本地事物其实可以认为是数据库提供的事务机制。说到数据库事务就不得不说,数据库事务中的四大特性:
A:原子性(Atomicity),一个事务中的所有操作,要么全部完成,要么全部不完成
C:一致性(Consistency),在一个事务执行之前和执行之后数据库都必须处于一致性状态
I:隔离性(Isolation),在并发环境中,当不同的事务同时操作相同的数据时,事务之间互不影响
D:持久性(Durability),指的是只要事务成功结束,它对数据库所做的更新就必须永久的保存下来
数据库事务在实现时会将一次事务涉及的所有操作全部纳入到一个不可分割的执行单元,该执行单元中
的所有操作要么都成功,要么都失败,只要其中任一操作执行失败,都将导致整个事务的回滚

(三)分布式事务

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

(四)分布式事务场景

1、单体系统访问多个数据库

一个服务需要调用多个数据库实例完成数据的增删改操作
在这里插入图片描述

2、多个微服务访问同一个数据库

多个服务需要调用一个数据库实例完成数据的增删改操作
在这里插入图片描述

3、多个微服务访问多个数据库

多个服务需要调用一个数据库实例完成数据的增删改操作
在这里插入图片描述

二、分布式事务解决方案

(一)全局事务

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

  • AP: Application 应用系统 (微服务)
  • TM: Transaction Manager 事务管理器 (全局事务管理)
  • RM: Resource Manager 资源管理器 (数据库)
    整个事务分成两个阶段:
  • 阶段一: 表决阶段,所有参与者都将本事务执行预提交,并将能否成功的信息反馈发给协调者。
  • 阶段二: 执行阶段,协调者根据所有参与者的反馈,通知所有参与者,步调一致地执行提交或者回滚。
    在这里插入图片描述
    优点
  • 提高了数据一致性的概率,实现成本较低

缺点

  • 单点问题: 事务协调者宕机
  • 同步阻塞: 延迟了提交时间,加长了资源阻塞时间
  • 数据不一致: 提交第二阶段,依然存在commit结果未知的情况,有可能导致数据不一致

(二)可靠消息服务

基于可靠消息服务的方案是通过消息中间件保证上、下游应用数据操作的一致性。假设有A和B两个系
统,分别可以处理任务A和任务B。此时存在一个业务流程,需要将任务A和任务B在同一个事务中处
理。就可以使用消息中间件来实现这种分布式事务。
在这里插入图片描述
第一步:消息由系统A投递到中间件

  1. 在系统A处理任务A前,首先向消息中间件发送一条消息
  2. 消息中间件收到后将该条消息持久化,但并不投递。持久化成功后,向A回复一个确认应答
  3. 系统A收到确认应答后,则可以开始处理任务A
  4. 任务A处理完成后,向消息中间件发送Commit或者Rollback请求。该请求发送完成后,对系统A而
    言,该事务的处理过程就结束了
  5. 如果消息中间件收到Commit,则向B系统投递消息;如果收到Rollback,则直接丢弃消息。但是
    如果消息中间件收不到Commit和Rollback指令,那么就要依靠"超时询问机制"。

超时询问机制 系统A除了实现正常的业务流程外,还需提供一个事务询问的接口,供消息中间件调用。当消息中
间件收到发布消息便开始计时,如果到了超时没收到确认指令,就会主动调用系统A提供的事务询
问接口询问该系统目前的状态。该接口会返回三种结果,中间件根据三种结果做出不同反应:

  • 提交:将该消息投递给系统B
  • 回滚:直接将条消息丢弃
  • 处理中:继续等待

第二步:消息由中间件投递到系统B
消息中间件向下游系统投递完消息后便进入阻塞等待状态,下游系统便立即进行任务的处理,任务处理
完成后便向消息中间件返回应答。

  • 如果消息中间件收到确认应答后便认为该事务处理完毕
  • 如果消息中间件在等待确认应答超时之后就会重新投递,直到下游消费者返回消费成功响应为止。

一般消息中间件可以设置消息重试的次数和时间间隔,如果最终还是不能成功投递,则需要手工干预。
这里之所以使用人工干预,而不是使用让A系统回滚,主要是考虑到整个系统设计的复杂度问题。
基于可靠消息服务的分布式事务,前半部分使用异步,注重性能;后半部分使用同步,注重开发成本。

(三)最大努力通知

最大努力通知也被称为定期校对,其实是对第二种解决方案的进一步优化。它引入了本地消息表来记录
错误消息,然后加入失败消息的定期校对功能,来进一步保证消息会被下游系统消费。
在这里插入图片描述
第一步:消息由系统A投递到中间件

  • 处理业务的同一事务中,向本地消息表中写入一条记录
  • 准备专门的消息发送者不断地发送本地消息表中的消息到消息中间件,如果发送失败则重试
    第二步:消息由中间件投递到系统B
  • 消息中间件收到消息后负责将该消息同步投递给相应的下游系统,并触发下游系统的任务执行
  • 当下游系统处理成功后,向消息中间件反馈确认应答,消息中间件便可以将该条消息删除,从而该
    事务完成
  • 对于投递失败的消息,利用重试机制进行重试,对于重试失败的,写入错误消息表
  • 消息中间件需要提供失败消息的查询接口,下游系统会定期查询失败消息,并将其消费
    这种方式的优缺点:
  • 优点: 一种非常经典的实现,实现了最终一致性。
  • 缺点: 消息表会耦合到业务系统中,如果没有封装好的解决方案,会有很多杂活需要处理。

(四)TCC事务

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

  • Try: 尝试待执行的业务:这个过程并未执行业务,只是完成所有业务的一致性检查,并预留好执 行所需的全部资源
  • Confifirm: 确认执行业务:确认执行业务操作,不做任何业务检查, 只使用Try阶段预留的业务 资源。通常情况下,采用TCC则认为
    Confifirm阶段是不会出错的。即:只要Try成功,Confifirm
    一定成功。若Confifirm阶段真的出错了,需引入重试机制或人工处理。
  • Cancel: 取消待执行的业务:取消Try阶段预留的业务资源。通常情况下,采用TCC则认为Cancel
    阶段也是一定成功的。若Cancel阶段真的出错了,需引入重试机制或人工处理
    在这里插入图片描述

在这里插入图片描述
TCC两阶段提交与XA两阶段提交的区别是:

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

TCC事务的优缺点:

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

三、Seata概述

Seata官方文档
2019 年 1 月,阿里巴巴中间件团队发起了开源项目 Fescar(Fast & EaSy Commit AndRollback),
其愿景是让分布式事务的使用像本地事务的使用一样,简单和高效,并逐步解决开发者们遇到的分布式
事务方面的所有难题。后来更名为 Seata,意为:Simple Extensible Autonomous Transaction
Architecture,是一套分布式事务解决方案。
Seata的设计目标是对业务无侵入,因此从业务无侵入的2PC方案着手,在传统2PC的基础上演进。它把
一个分布式事务理解成一个包含了若干分支事务的全局事务。全局事务的职责是协调其下管辖的分支事
务达成一致,要么一起成功提交,要么一起失败回滚。此外,通常分支事务本身就是一个关系数据库的
本地事务。
在这里插入图片描述

(一)Seata主要三个重要组件

  • TC:Transaction Coordinator 事务协调器,管理全局的分支事务的状态,用于全局性事务的提交 和回滚。
  • TM:Transaction Manager 事务管理器,用于开启、提交或者回滚全局事务。
  • RM:Resource Manager 资源管理器,用于分支事务上的资源管理,向TC注册分支事务,上报分
    支事务的状态,接受TC的命令来提交或者回滚分支事务。
    在这里插入图片描述

(二)Seata的执行流程

  1. A服务的TM向TC申请开启一个全局事务,TC就会创建一个全局事务并返回一个唯一的XID
  2. A服务的RM向TC注册分支事务,并及其纳入XID对应全局事务的管辖
  3. A服务执行分支事务,向数据库做操作
  4. A服务开始远程调用B服务,此时XID会在微服务的调用链上传播
  5. B服务的RM向TC注册分支事务,并将其纳入XID对应的全局事务的管辖
  6. B服务执行分支事务,向数据库做操作
  7. 全局事务调用链处理完毕,TM根据有无异常向TC发起全局事务的提交或者回滚
  8. TC协调其管辖之下的所有分支事务, 决定是否回滚

(三)Seata实现2PC与传统2PC的差别

  1. 架构层次方面,传统2PC方案的 RM 实际上是在数据库层,RM本质上就是数据库自身,通过XA协
    议实现,而 Seata的RM是以jar包的形式作为中间件层部署在应用程序这一侧的。
  2. 两阶段提交方面,传统2PC无论第二阶段的决议是commit还是rollback,事务性资源的锁都要保
    持到Phase2完成才释放。而Seata的做法是在Phase1 就将本地事务提交,这样就可以省去Phase2
    持锁的时间,整体提高效率

四、Seata服务端安装部署—windows案例

1、下载seata并解压

下载地址:https://github.com/seata/seata/releases/tag/v1.5.2
下载的版本参考:
springcloudalibaba-seata版本参考
在这里插入图片描述
解压后路径
在这里插入图片描述

2、修改配置文件

参考官网配置:[https://github.com/seata/seata/tree/master/script]

修改 seata\conf\application.yml 的内容主要有以下三部分:

1. 添加存储方式

在这里插入图片描述

  store:
    mode: db
    db:
      datasource: druid
      db-type: mysql
      driver-class-name: com.mysql.cj.jdbc.Driver
      url: jdbc:mysql://127.0.0.1:3306/seata?rewriteBatchedStatements=true
      user: root
      password: 123456

创建上面配置中的seata数据库并根据解压路径seata\script\server\db\mysql.sql文件创建表
官方sql脚本连接https://github.com/seata/seata/blob/master/script/server/db/mysql.sql

2. 添加注册中心
  registry:
    type: nacos
    nacos:
      application: seata-server
      server-addr: 127.0.0.1:8848
      group: SEATA_GROUP
      namespace:
      cluster: default
      username:
      password:
3. 添加配置中心
seata:
  config:
    type: nacos
    nacos:
      server-addr: 127.0.0.1:8848
      namespace:
      group: SEATA_GROUP
      username:
      password:
5、最终的application.yml文件内容:
server:
  port: 7091

spring:
  application:
    name: seata-server

logging:
  config: classpath:logback-spring.xml
  file:
    path: ${
   user.home}/logs/seata
  extend:
    logstash-appender
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值