带你读懂事务(下)、分布式事务

简介: 带你读懂事务(下)、分布式事务

上篇文章我们说了事务的基本概念,以及事务的几种隔离级别,但是说的都是单机事务。随着现在微服务的流行,很多时候我们需要考虑的事务,往往都不再是单节点的事务,这种分布式的事务给我们造成了很大的麻烦,事实上这也是微服务中比较难处理的问题。我们先来看下现在业界分布式事务的解决方案都有哪些:


两阶段提交(2PC)


两阶段提交,就是把原本的事务拆解成了准备阶段和提交阶段这两个阶段(prepare和commit/rollback),在这个阶段中,需要额外的事务管理者TM(Transaction Manager)来对事务的状态进行管理,各个分支事务参与方则称为RM(Resource Manager),这个阶段的流程如下:


1686815847602.png


我们可以看到,当各个RM的prepare动作成功之后,便向TM发出ok的信息,TM收到RM ok的信息之后,认为事务已经可以提交,就向各个TM发出提交的命令。在这个过程中,如果有任何一个prepare动作失败或者是commit失败,都会导致最终的rollback。


TCC


TCC是一种采用了补偿机制的事务,它把事务分成了以下三个阶段:

  • Try 阶段:主要是对业务系统做检测及资源预留
  • Confirm 阶段:主要是对业务系统做确认提交,Try阶段执行成功并开始执行 Confirm阶段时,默认 Confirm阶段是不会出错的。即:只要Try成功,Confirm一定成功。
  • Cancel 阶段:主要是在业务执行错误,需要回滚的状态下执行的业务取消,预留资源释放

我们举个例子,假如说现在有一个业务流程是电商的付款之后扣库存,则这里涉及到了订单和库存服务,那么如果要使用TCC的话,业务都需要做什么改造


订单服务
try:设置一个中间状态,来表示用户正在支付中
confirm:将状态改为支付成功
cancel:把订单设置为取消
库存服务
try:先用一个冻结库存字段保存冻结库存数,而不是直接扣掉库存
confirm:扣掉库存并清除冻结库存的记录
cancel:把库存加回去


我们可以看出来,TCC和2PC看起来很相似,都是分为了两个阶段去提交,但是实际运用上还是有相当的差别。2PC是XA的标准实现,这种解决方案多数都是需要数据库层面的支持的,因此2PC其实是强一致性事务,因此锁的时间会比较长,高并发之下会有性能问题。TCC的话,由于有中间状态,一致性会差一些,但是性能相对比较友好,只不过对业务的侵入性太大了,需要比较高的改造成本。


本地消息表


这种解决方案其实是基于base理论的,base理论是指Basically Available(基本可用的),Soft state(软状态),Eventual consistency(最终一致性)。它最开始是由eBay提出的,基本思路如下:

消息生产方,需要额外建一个消息表,并记录消息发送状态。消息表和业务数据要在一个事务里提交,也就是说他们要在一个数据库里面。然后消息会经过MQ发送到消息的消费方。如果消息发送失败,会进行重试发送。

消息消费方,需要处理这个消息,并完成自己的业务逻辑。此时如果本地事务处理成功,表明已经处理成功了,如果处理失败,那么就会重试执行。如果是业务上面的失败,可以给生产方发送一个业务补偿消息,通知生产方进行回滚等操作。

生产方和消费方定时扫描本地消息表,把还没处理完成的消息或者失败的消息再发送一遍。如果有靠谱的自动对账补账逻辑,这种方案改造成本相对较低,并且还能够很容易的做成通用能力,因此也是现在使用的比较多的。

事务消息

事务消息则需要引入mq,它的流程如下:


主流程
 (1) 发送消息(half消息)。
 (2) 服务端响应消息写入结果。
 (3) 根据发送结果执行本地事务(如果写入失败,此时half消息对业务不可见,本地逻辑不执行)。
 (4) 根据本地事务状态执行Commit或者Rollback(Commit操作生成消息索引,消息对消费者可见)
补偿流程
 (1) 对没有Commit/Rollback的事务消息(pending状态的消息),从服务端发起一次“回查”
 (2) Producer收到回查消息,检查回查消息对应的本地事务的状态
 (3) 根据本地事务状态,重新Commit或者Rollback


这种方案比较依赖mq的可靠性,如果要采用这种方案,建议mq选型RocketMq。


FMT(FrameWork Managed Transactions)

这是一个比较特殊的分布式事务解决方案,因为这种方式把分布式事务的处理完全交给了框架,比较典型的是Seata的At模式,这种模式完全不需要修改代码,只需要加上一个注解在事务方法上,就可以完成分布式事务。其原理是业务数据提交时,自动拦截所有的SQL,分别保存SQL对数据修改前后的快照,如果分布式事务成功了,那我们后续只需清理每个数据源中对应的日志数据即可。如果分布式事务需要回滚,就要根据日志数据自动产生用于补偿的逆向SQL。

优点是业务代码改造量是非常小的,但是缺点也很明显,一是性能损耗比较明显,每次修改都需要插入一条log,二是复杂的sql就不能搞得定了。


其他

这里面都是一些用的比较少的,比如3PC,这种方案目前还几乎只存在于理论中,因为不好落地且不实用。

相关实践学习
消息队列RocketMQ版:基础消息收发功能体验
本实验场景介绍消息队列RocketMQ版的基础消息收发功能,涵盖实例创建、Topic、Group资源创建以及消息收发体验等基础功能模块。
消息队列 MNS 入门课程
1、消息队列MNS简介 本节课介绍消息队列的MNS的基础概念 2、消息队列MNS特性 本节课介绍消息队列的MNS的主要特性 3、MNS的最佳实践及场景应用 本节课介绍消息队列的MNS的最佳实践及场景应用案例 4、手把手系列:消息队列MNS实操讲 本节课介绍消息队列的MNS的实际操作演示 5、动手实验:基于MNS,0基础轻松构建 Web Client 本节课带您一起基于MNS,0基础轻松构建 Web Client
目录
相关文章
|
5月前
|
SQL 关系型数据库 MySQL
乐观锁在分布式数据库中如何与事务隔离级别结合使用
乐观锁在分布式数据库中如何与事务隔离级别结合使用
|
8月前
|
运维 监控 Java
Spring Cloud Alibaba分布式事务问题之事务commit失败如何解决
Spring Cloud Alibaba提供了一套在Spring Cloud框架基础上构建的微服务解决方案,旨在简化分布式系统的开发和管理;本合集将探讨Spring Cloud Alibaba在实际应用中的部署和使用技巧,以及该框架常见问题的诊断方法和解决步骤。
|
Oracle 关系型数据库 分布式数据库
OBCP第五章 分布式事务高级技术-分布式两阶段提交
OBCP第五章 分布式事务高级技术-分布式两阶段提交
129 0
|
Oracle 关系型数据库 MySQL
第四章:OceanBase集群技术架构(分布式事务、MVCC、事务隔离级别)
第四章:OceanBase集群技术架构(分布式事务、MVCC、事务隔离级别)
411 0
|
SQL OceanBase Python
OBCP第五章 分布式事务高级技术-分布式两阶段提交
OBCP第五章 分布式事务高级技术-分布式两阶段提交
216 0
|
8月前
|
消息中间件 Dubbo 应用服务中间件
分布式事物【Hmily实现TCC分布式事务、Hmily实现TCC事务、最终一致性分布式事务解决方案】(七)-全面详解(学习总结---从入门到深化)
分布式事物【Hmily实现TCC分布式事务、Hmily实现TCC事务、最终一致性分布式事务解决方案】(七)-全面详解(学习总结---从入门到深化)
214 0
|
3月前
|
SQL 关系型数据库 MySQL
乐观锁在分布式数据库中如何与事务隔离级别结合使用
乐观锁在分布式数据库中如何与事务隔离级别结合使用
|
30天前
|
消息中间件 架构师 数据库
本地消息表事务:10Wqps 高并发分布式事务的 终极方案,大厂架构师的 必备方案
45岁资深架构师尼恩分享了一篇关于分布式事务的文章,详细解析了如何在10Wqps高并发场景下实现分布式事务。文章从传统单体架构到微服务架构下分布式事务的需求背景出发,介绍了Seata这一开源分布式事务解决方案及其AT和TCC两种模式。随后,文章深入探讨了经典ebay本地消息表方案,以及如何使用RocketMQ消息队列替代数据库表来提高性能和可靠性。尼恩还分享了如何结合延迟消息进行事务数据的定时对账,确保最终一致性。最后,尼恩强调了高端面试中需要准备“高大上”的答案,并提供了多个技术领域的深度学习资料,帮助读者提升技术水平,顺利通过面试。
本地消息表事务:10Wqps 高并发分布式事务的 终极方案,大厂架构师的 必备方案
|
2月前
|
监控
Saga模式在分布式系统中保证事务的隔离性
Saga模式在分布式系统中保证事务的隔离性
|
4月前
Saga模式在分布式系统中如何保证事务的隔离性
Saga模式在分布式系统中如何保证事务的隔离性