分布式事务及seata解决方案

分布式事务概念

分布式系统会把一个应用系统拆分为可独立部署的多个服务,因此需要服务与服务之间远程协作才能完成事务操作,这种分布式系统环境下由不同的服务之间通过网络远程协作完成事务称之为分布式事务

例如注册服务之后,送优惠卷和积分,组成一个事务,分别在不同的服务中,这种情况就是分布式事务,单体系统跨数据库实例或者多个服务访问一个数据库实例组成事务的情况也算分布式事务

CAP原则和BASE理论

CAP原则

C:一致性 是指写操作后的读操作可以读取到最新的数据状态,当数据分布在多个节点上,从任意结点读取到的数据都是最新的状态

A:可用性是指任何事务操作都可以得到响应结果,且不会出现响应超时或响应错误

P:分区容错性 通常分布式系统的各各结点部署在不同的子网,这就是网络分区,不可避免的会出现由于网络问题而导致结点之间通信失败,此时仍可对外提供服务,这叫分区容忍性

CAP组合方式

P分区容错性是分布式系统具备的基本能力,在分布式系统中,分布式事务不会同时具备CAP三个特性,因为具备了P的前提下,C与A是矛盾的

实现一致性C,为了防止查询到不一样的结果,需要将数据暂时锁定,待数据同步后解锁,如果同步失败则会返回错误信息和超时信息,而A是无论任何时候都可以查询数据,这就造成了C和A的矛盾性

  • 在生产场景中,最常用的是AP组合,放弃一致性,追求可用性和分区容错性,这里不是完全放弃一致性,这里的一致性指的是最终一致性也就是BASE理论(柔性事务)
  • CP 放弃可用性,追求强一致性,例如zookeeper就是追求强一致性,比如跨行转账,等待双方银行系统都完成才算事务完成

BASE理论

BASE 是 Basically Available(基本可用)Soft state(软状态)和 Eventually consistent (最终一致性),也就是AP原则,也成为柔性事务

  • 基本可用:分布式系统在出现故障时,允许损失部分可用功能,保证核心功能可用
  • 软状态:由于不要求强一致性,所以BASE允许系统中存在中间状态(也叫软状态),这个状态不影响系统可用性,如订单的"支付中"、"数据同步中"等状态,待数据最终一致后状态改为"成功"状态
  • 最终一致性:不追求强一致性,数据最终会一致,用户可以感知和接受

2PC两阶段提交协议

两阶段提交协议分为两个阶段,第一阶段 准备阶段 ,第二个阶段 提交阶段,基于数据库支持2PC协议,例如oracle和mysql都支持2PC协议

两个阶段

准备阶段( Prepare phase ):事务管理器给每个参与者发送Prepare消息,每个数据库参与者在本地执行事务,并写本地的Undo/Redo日志,此时事务没有提交

undo:回滚日志,反向操作

Redo:记录修改后的日志,用于持久化,写完的数据在内存中,事务提交之后,刷新到磁盘持久化

binlog:属于mysql server层面的二进制日志,记录所有的写操作,主要作为主从复制使用

提交阶段( commit phase ): 如果事务管理器收到了参与者的执行失败或者超时消息时,直接给每个参与者发送回滚(Rollback)消息,否则,发送提交(Commit)消息,参与者根据事务管理器的指令执行提交或者回滚操作,并释放事务处理过程中使用的锁资源。注意:必须在最后阶段释放锁资源

DTP分布式事务处理模型

2PC的传统方案是在数据库层面实现的,如Oracle、 MSQL都支持2PC协议,为了统一标准减少行业内不必要的对接成本,需要制定标准化的处理模型及接口标准,国际开放标准组织Open Group定义了分布式事务处理模型DTP Distributed Transaction Processing Reference Model

  • AP(Application Program): 即应用程序,可以理解为使用DTP分布式事务的程序。
  • RM(Resource Manager) :即资源管理器,可以理解为事务的参与者,一般情况下是指一个数据库实例,通过资源管理器对该数据库进行控制,资源管理器控制着分支事务
  • TM(Transaction Manager) : 事务管理器,负责协调和管理事务,事务管理器控制着全局事务,管理事务生命周期,并协调各个RM。全局事务是指分布式事务处理环境中,需要操作多个数据库共同完成一个工作,这个工作即是一个全局事务

XA方案

DTP模型定义TM和RM之间通讯的接口规范叫XA,简单理解为数据库提供的2PC接口协议,甚于数据库的XA协议来实现2PC又称为XA方案,XA方案是强一致性的方案,数据库必须支持XA方案。seata中的XA方案与传统方案就多了一个TM事务管理者

  • TM向AP提供 应用程序编程接口,AP通过TM提交及回滚事务
  • TM交易中间件通过XA接口来通知RM数据库事务的开始、结束以及提交、回滚等

XA方案的两阶段

第一阶段

一阶段也叫做准备阶段,事务协调者 会向 资源管理器 发起一个准备的请求,也就是告诉他可以执行sql,但不允许提交,随后RM执行sql但不提交,将执行状态反馈给TC

第二阶段

事务协调者收到 RM 的反馈之后,就会进行判断,如果都执行成功了,就通知这些 RM执行提交操作,然后 RM 收到请求,就把事务提交了,整个事务也就结束了,如果有任意一个服务执行失败了,那么事务协调者就会通知这些RM,让他们全部回滚.

Seata中实现XA方案

Seata 的 XA 模式和基于数据库的XA方案基本类似,只不过是多了一个TM(事务管理者),在上述XA中,决策者是TC,而在Seata中的决策者是TM,真正干活的其实还是TC

第一阶段

TM 一上来就是要去注册全局事务,作为分布式事务的入口,接下来就会去调用各个分支事务. 每个分支事务中又有一个 RM,RM 就回去 TC 里面注册分支事务,然后执行业务 sql,但是执行完后不能提交,只是去报告一下事务的状态

第二阶段

TM 这里的入口方法执行完了以后,调用 TC对全局事务进行提交或者回滚,随后 TC 就会去检查各个分支事务报告的状态,然后向 RM 发送一个信号,如果第一阶段都执行成功了,那么就提交,反之,则进行回滚,RM 收到信号之后就可以进行 提交/回滚 事务了

XA方案的问题

在准备阶段RM执行实际业务,但不提交事务,资源锁定,在提交阶段,TM会接受RM的所有回复,只要有一个RM执行失败则回滚事务,否则提交事务,资源锁释放

1、需要本地数据库支持XA协议

2、资源锁需要等两个阶段结束才释放,性能较差

AT方案

AT模式同样是分阶段提交的事务模型,不过缺弥补了XA模型中资源锁定周期过长的缺陷,简而言之就是不会锁定资源

AT模式支持的数据库有:MySQL、Oracle、PostgreSQL和 TiDB

Seata实现AT方案

AT 模模式也是分阶段性提交的事务模型. 他的出现正式为了解决 XA 模式中资源锁定周期过长的一个缺陷,AT方案是最终一致性方案,也是Seata解决方案中选择最多的方案

第一阶段

TM 去开启全局事务,作为分布式事务的入口,接着又会调用每一个分支事务 ,然后每个分支事务里的 rm 都会去注册分支事务,并执行本地的业务 sql,然后直接提交,XA是不提交 因此 AT 模式就不需要像 XA 那样锁定资源,性能上要优于 XA 模式.

AT 模式在执行 sql 之前,RM 会给当前数据生成一个快照,这个快照的名字叫 "undo log",那么这样就即使有分支事务执行 sql 的时候失败了,也可以根据快照恢复如初

第二阶段

TM 看到业务结束了,就会去通知 TC提交或者回滚事务,那么 TC 就会判断是提交还是回滚.

如果分支事务的状态都是成功的,那就可以把第一阶段准备的快照给删了(删快照这个动作是异步的,因为第一阶段都成功了,也提交了,后面的事情就可以用一个线程独立去做,提高了效率

如果第一阶段有人失败了,就要基于 undo log 恢复数据,恢复以后这个 log 也就没用了,最后也会删除

XA模式和AT模式的区别

  • XA模式一阶段不提交事务,锁定资源;AT模式一阶段直接提交,不锁定资源。
  • XA模式依赖数据库机制实现回滚;AT模式利用数据快照实现数据回滚。
  • XA模式强一致, AT模式最终一致

Seata TCC模式

TCC模式与AT模式非常相似,每阶段都是独立事务,不同的是TCC通过人工编码来实现数据恢复,也是最终一致型,依赖Confirm和Cancel的补偿操作

需要实现三个方法:

  • Try:资源的检测和预留;
  • Confirm:完成资源操作业务;要求 Try 成功 Confirm 一定要能成功。
  • Cancel:预留资源释放,可以理解为try的反向操作
    假设一个扣除银行卡余额的业务。假设账户A原来余额是100,需要余额扣减20元

Try阶段

检查余额是否充足,如果充足,则冻结金额增加20元,可用余额扣除80

总金额 = 冻结金额 + 可用金额,数量依然是100不变。事务直接提交无需等待其它事务

Confirm阶段

确认可以提交,不过之前冻结金额已经扣减过了,这里只要清除冻结金额就好了

总金额 = 冻结金额 + 可用金额 = 0 + 80 = 80元

Cancel阶段

需要回滚,那么就要释放冻结金额,恢复可用金额

总金额 = 冻结金额 + 可用金额 = 20 + 80 = 100元
TCC不用加全局锁就实现了事务隔离, 性能上优于AT

TCC模式的优缺点

优点:

  • 一阶段完成直接提交事务,释放数据库资源,性能好
  • 相比AT模型,无需生成快照,无需使用全局锁,性能最强
  • 不依赖数据库事务,而是依赖补偿操作,可以用于非事务型数据库

缺点:

  • 有代码侵入,需要人为编写try、Confirm和Cancel接口,太繁琐
  • 软状态,事务是最终一致
  • 需要考虑Confirm和Cancel的失败情况,做好幂等处理

空回滚和业务悬挂

空回滚

当某分支事务的try阶段阻塞时,可能导致全局事务超时而触发二阶段的cancel操作。在未执行try操作时先执行了cancel操作,这时cancel不能做回滚,就是空回滚
方案: 执行cancel操作时,应当判断try是否已经执行,如果尚未执行,则应该空回滚

业务悬挂

对于已经空回滚的业务,之前被阻塞的try操作恢复,继续执行try,就永远不可能confirm或cancel ,事务一直处于中间状态,就是业务悬挂
**方案:**执行try操作时,应当判断cancel是否已经执行过了,如果已经执行,应当阻止空回滚后的try操作,避免悬挂

Seata SAGA模式

Saga 模式是Seata提供的长事务解决方案,在 Saga 模式中,业务流程中每个参与者都提交本地事务,当某个参与者出现失败,则补偿前面已经成功的参与者,一阶段正向服务和二阶段补偿服务都有业务开发实现,这里不再介绍该模式

相关推荐
天冬忘忧4 小时前
Kafka 工作流程解析:从 Broker 工作原理、节点的服役、退役、副本的生成到数据存储与读写优化
大数据·分布式·kafka
IT枫斗者9 小时前
如何解决Java EasyExcel 导出报内存溢出
java·服务器·开发语言·网络·分布式·物联网
求积分不加C9 小时前
Kafka怎么发送JAVA对象并在消费者端解析出JAVA对象--示例
java·分布式·kafka·linq
GDDGHS_10 小时前
“Kafka面试攻略:核心问题与高效回答”
分布式·面试·kafka
꧁薄暮꧂11 小时前
kafka中的数据清理策略
数据库·分布式·kafka
hong16168811 小时前
大数据技术Kafka详解:消息队列(Messages Queue)
大数据·分布式·kafka
eternal199513 小时前
优化算法|基于Deep-Q-Network(DQN)的邻域搜索算法求解分布式柔性作业车间调度问题
分布式·算法
呼啦啦啦啦啦啦啦啦15 小时前
【Rabbitmq篇】RabbitMQ⾼级特性----持久性,发送⽅确认,重试机制
分布式·rabbitmq
꧁薄暮꧂21 小时前
kafka是如何做到高效读写
分布式·kafka
隔着天花板看星星21 小时前
Kafka-创建topic源码
大数据·分布式·中间件·kafka