微服务分布式事务组件 Seata(一)

前言

事务简介

事务(Transaction)是访问并可能更新数据库中各种数据项的一个程序执行单元(unit)。 在关系数据库中,一个事务由一组SQL语句组成。 事务应该具有4个属性:原子性、一致性、隔离性、持久性。这四个属性通常称为ACID特性。
  • 原子性(atomicity):事务是一个不可分割的工作单位, 事务中包括的诸操作要么都做,要么都不做。
  • 一致性(consistency):事务必须是使数据库从一个一致性状态变到另一 个一 致性状态, 事务的中间状态不能被观察到的。
  • 隔离性(isolation) : 一个事务的执行不能被其他事务干扰。即一个事务内部的操作及使用的数据对并发的其他事务是隔离的,并发执行的各个事务之间不能互相干扰。隔离性又分为四个级别:读未提交(read uncommitted)、读已提交(read committed,解决脏读)、可重复读(repeatable read,解决虚读)、串行化(serializable,解决幻读)。
  • 持久性(durability) :持久性也称永久性(permanence) ,指一个事务一旦提交, 它对数据库中数据的改变就应该是永久性的。接下来的其他操作或故障不应该对其有任何影响。任何事务机制在实现时,都应该考虑事务的ACID特性,包括:本地事务、分布式事务,及时不能都很好的满足,也要考虑支持到什么程度。

本地事务

@Transactional,大多场景下,我们的应用都只需要操作单一的数据库,这种情况下的事务称之为本地事务(Local Transaction),本地事务的 ACID 特性是数据库直接提供支持。本地事务应用架构如下

微服务分布式事务组件 Seata

在 JDBC 编程中,我们通过java.sql.Connection对象来开启、关闭或者提交事务

Connection conn = ... // 获取数据库连接
conn.setAutoCommit(false);// 关闭自动提交
try{
  // ... 执行增删改查 sql
  conn.commit(); // 提交事务
} catch(Exception e) {
  conn.rollback(); // 事务回滚
} finally {
  conn.close(); //关闭连接
}

分布式事务

下面两种情况如果是按照之前的本地事务,是无法保证事务的。

微服务分布式事务组件 Seata

微服务分布式事务组件 Seata

一、什么是 Seata

Seata是一款开源的分布式事务解决方案, 致力于提供高性能和简单易用的分布式事务服务。Seata 将为用户提供了ATTCCSAGAXA 事务模式,为用户打造一站式的分布式解决方案。AT 模式是阿里首推的模式,阿里云上有商用版本的 GTS (Global Transaction Service全局事务服务)

常见的分布式事务解决方案

  1. seata 阿里分布式事务框架
  2. 消息队列
  3. SAGA
  4. XA

他们有一个共同点,都是“两阶段(2PC)”。“两阶段”是指完成整个分 布式事务,划分成两个步骤完成。
实际上,这四种常见的分布式事务解决方案,分别对应着分布式事务的四种模式: AT、 TCC、 Saga、 XA;

2PC两阶段提交(Two-Phase Commit)协议:
顾名思义,分为两个阶段:Prepare 和 Commit

1.1、Prepare:提交事务请求

基本流程如下

微服务分布式事务组件 Seata

微服务分布式事务组件 Seata

  1. 询问协调者向所有参与者发送事务请求,询问是否可执行事务操作,然后等待各个参与者的响应。
  2. 执行各个参与者接收到协调者事务请求后,执行事务操作(例如更新一个关 系型数据库表中的记录),并将 Undo 和 Redo 信息记录事务日志中。
  3. 响应如果参与者成功执行了事务并写入Undo和Redo信息,则向协调者返回YES响应,否则返回NO响应。当然,参与者也可能宕机,从而不会返回响应。

1.2、正常提交事务

微服务分布式事务组件 Seata

微服务分布式事务组件 Seata

  1. commit请求协调者向所有参与者发送Commit请求。
  2. 事务提交参与者收到 Commit 请求后,执行事务提交,提交完成后释放事务执行期占用的所有资源。
  3. 反馈结果参与者执行事务提交后向协调者发送Ack响应。
  4. 完成事务接收到所有参与者的Ack响应后,完成事务提交。

1.3、中断事务

在执行Prepare步骤过程中,如果某些参与者执行事务失败、宕机或与协调者之间的网络中断,那么协调者就无法收到所有参与者的 YES 响应,或者某个参与者返回了 No 响应,此时,协调者就会进入回退流程,对事务进行回退。流程如下图红色部分(将Commit请求替换为红色的Rollback 请求)

微服务分布式事务组件 Seata

  1. rollback请求协调者向所有参与者发送Rollback请求。
  2. 事务回滚参与者收到Rollback后,使用Prepare阶段的Undo日志执行事务回滚,完成后释放事务执行期占用的所有资源。
  3. 反馈结果参与者执行事务回滚后向协调者发送 Ack 响应。
  4. 中断事务接收到所有参与者的Ack响应后,完成事务中断。

二、2PC 的问题

  1. 同步阻塞参与者在等待协调者的指令时,其实是在等待其他参与者的响应,在此过程中,参与者是无法进行其他操作的,也就是阻塞了其运行。倘若参 与者与协调者之间网络异常导致参与者一直收不到协调者信息,那么会导致参与者一直阻塞下去。
  2. 单点在2PC中,一切请求都来自协调者,所以协调者的地位是至关重要的,如果协调者宕机,那么就会使参与者一直阻塞并一直占用事务资源。如果协调者也是分布式,使用选主方式提供服务,那么在一个协调者挂掉后, 可以选取另一个协调者继续后续的服务,可以解决单点问题。但是,新协调者无法知道上一个事务的全部状态信息(例如已等待Prepare响应的时长等),所以也无法顺利处理上一个事务。
  3. 数据不一致Commit事务过程中Commit请求/Rollback请求可能因为协调者宕机或协调者与参与者网络问题丢失,那么就导致了部分参与者没有收到Commit/Rollback请求,而其他参与者则正常收到执行了CommitRollback操作,没有收到请求的参与者则继续阻塞。这时,参与者之间的数据就不再一 致了。当参与者执行CommitRollback后会向协调者发送Ack,然而协调者不论是否收到所有的参与者的Ack,该事务也不会再有其他补救措施了,协调者能做的也就是等待超时后像事务发起者返回一个“我不确定该事务是否成功”。
  4. 环境可靠性依赖协调者Prepare请求发出后,等待响应,然而如果有参与者宕机或与协调者之间的网络中断,都会导致协调者无法收到所有参与者的响应,那么在 2PC 中,协调者会等待一定时间, 然后超时后,会触发事务中断,在这个过程中,协调者和所有其他参与者都是出于阻塞的。这种机制对网络问题常见的现实环境来说太苛刻了。

三、AT 模式(auto transaction)

AT模式是一种无侵入的分布式事务解决方案。
阿里seata框架,实现了该模式。
在AT模式下,用户只需关注自己的“业务SQL”,用户的“业务SQL”作为一阶段, Seata 框架会自动生成务的二阶段提交和回滚操作。

微服务分布式事务组件 Seata

  • 一阶段

在一阶段,Seata 会拦截“业务SQL”,首先解析 SQL 语义,找到“业务 SQL”要更新的业务数据,在业务数据被更新前,将其保存成“before image”,然后执行“业务SQL”更新业务数据,在业务数据更新之后,再将其保存成”after image”,最后生成行锁。以上操作全部在一个数据库事务内完成, 这样保证了一阶段操作的原子性。

微服务分布式事务组件 Seata

  • 二阶段提交

二阶段如果是提交的话,因为“业务SQL”在一阶段已经提交至数据库,所以 Seata 框架只需将一阶段保存的快照数据和行锁删掉,完成数据清理即可。

微服务分布式事务组件 Seata

  • 二阶段回滚

二阶段如果是回滚的话,Seata 就需要回滚一阶段已经执行的“业务SQL”,还原业务数据。回滚方式便是用“before image”还原业务数据;但在还原前要首先要校验脏写,对比“数据库当前业务数据”和“after image”,如果两份数据完全一致就说明没有脏写, 可以还原业务数据,如果不一致就说明有脏写,出现脏写就需要转人工处理。

微服务分布式事务组件 Seata

四、TCC 模式

TCC 模式需要用户根据自己的业务场景实现 Try、Confirm 和 Cancel 三个操作;事务发起方在一阶段执行 Try 方式,在二阶段提交执行 Confim 方法,二阶段回滚执行 Cancel 方法。

缺点:
侵入性强,并且得自己实现相关事务控制逻辑
优点:
在整个过程中基本没有锁,性能更强

微服务分布式事务组件 Seata

微服务分布式事务组件 Seata

五、基于消息队列实现分布式事务

微服务分布式事务组件 Seata

六、Seata 详细说明

在Seata的架构中,一共有三个角色:
TC (Transaction Coordinator) - 事务协调者
维护全局和分支事务的状态,驱动全局事务提交或回滚。
TM (Transaction Manager) - 事务管理器
定义全局事务的范围:开始全局事务、提交或回滚全局事务。
RM (Resource Manager) - 资源管理器
管理分支事务处理的资源,与TC交谈以注册分支事务和报告分支事务的状态,并驱动分支事务提交或回滚。
其中,TC为单独部署的Server服务端,TM和RM为嵌入到应用中的Client客户端。

在 Seata 中,一个分布式事务的生命周期如下

微服务分布式事务组件 Seata

1.TM 请求 TC 开启一个全局事务。TC 会生成一个 XID 作为该全局事务的编号。XID 会在微服务的调用链路中传播,保证将多个微服务的子事务关联在一起。
2.RM 请求 TC 将本地事务注册为全局事务的分支事务,通过全局事务的XID进行关联。
3.TM 请求 TC 告诉 XID 对应的全局事务是进行提交还是回滚。
4.TC 驱动 RM 们将 XID 对应的自己的本地事务进行提交还是回滚。

本作品采用《CC 协议》,转载必须注明作者和本文链接
讨论数量: 0
(= ̄ω ̄=)··· 暂无内容!

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!
未填写
文章
247
粉丝
18
喜欢
217
收藏
62
排名:731
访问:9753
私信
所有博文
社区赞助商