分布式事务的解决思路与方案

一、事务的种类与场景

本地事务实际上就是指数据库的事务,参考《MySQL —— 事务与隔离级别总结

分布式事务指的是在分布式环境下,由多个本地事务组成,多个系统之间如何保证事务之间的原子性、一致性等问题。例如多个系统访问同一个数据库,多个系统访问多个数据库,等等这些场景,都数据分布式事务的讨论范围。

二、分布式事务解决方案

介绍四个业界应用比较广泛的分布式解决方案:全局事务、可靠消息服务、最大努力通知、TCC事务(补偿型事务)。

2.1 全局事务

全局事务基于DTP 模型实现,这是由X/Open 组织提出的一种分布式事务模型,全称为“分布式事务处理参考模型”。

DTP规定要实现分布式事务,需要三种角色:

AP:Application 应用系统
TM:Transaction Manager 事务管理器
RM:Resource Manager 资源管理器

在 DTP 模型中,整个系统的事务分为两个阶段,即 2PC(2 Phrase Commit):

1、准备阶段:也可以叫表决阶段或投票阶段。TM 向 各个 AP 发送准备命令,并告诉各本地事务即将提交事务。TM同步等待参与者的响应。此阶段各本地事务已经完成了事务逻辑,就差一步提交操作。
2、提交阶段:TM 根据响应结果,决定发送提交或回滚命令。若都准备成功,则提交事务;但只要有一个返回失败,就全部回滚。

在这里插入图片描述
全局事务的优缺点:

优点:由于是同步阻塞协议,因此可以保证数据的强一致性。资源管理器本身就是数据库,实现不需要增加太多的代码逻辑,实现成本低。流程简单。
缺点
1、单点故障问题:TM 是全局事务的协调者、管理者,绝不能出现单点故障问题。
2、同步阻塞:增加了资源阻塞时间,可能存在死锁的风险,需要增加超时机制。
3、一致性问题:二阶段提交可能存在失败的情况,导致数据不一致。

总之,该模型是旨在保证强一致性的全局事务模型,但由于其模型仍然简单粗糙,在实际生产中,还需要进一步扩展和细化。

2.2 可靠消息事务

基于可靠消息服务的方案是通过消息中间件保证上、下游应用数据操作的一致性。基本可以理解为就是 RocketMQ提供的事务消息,参考《Spring Cloud —— RocketMQ 的消息类型

假设有A和B两个系统,分别可以处理任务A和任务B。此时存在一个业务流程,需要将任务A和任务B在同一个事务中处理,就可以使用消息中间件来实现这种分布式事务。
在这里插入图片描述

2.3 最大努力通知

最大努力通知也被称为定期校对,其实是对可靠消息事务方案的进一步优化。它引入了本地消息表来记录错误消息,然后加入失败消息的定期校对功能,来进一步保证消息会被下游系统消费。

这种方案由于本身需要引入许多额外的补偿结构,如本地消息表、失败消息表、定期校对者等等,增加了业务耦合度,提高了实现复杂度,因此在业界并不是特别流行,但不得不说的确是增加了系统事务的安全性降低了事故风险。
在这里插入图片描述
第一步:消息由A系统投递到中间件

1、处理业务的同一事务中,向本地消息表中写入一条记录
2、准备专门的消息发送者,轮询本地消息表,将需要发送的(未发送的或失败的)事务消息发送到中间件

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

1、消息中间件收到消息后负责将该消息同步投递到下游系统,并触发下游系统的任务执行
2、当下游系统处理成功后,向消息中间件反馈确认应答,消息中间件便可以将该消息删除,表示该事务完成
3、如果投递失败,增加重试机制,对重试失败的,写入错误消息表
4、消息中间件需要提供失败消息的回查接口,下游系统会定期查询失败消息,自行消费。

优点:一种非常经典的分布式事务解决方案,最大限度保证最终一致性。
缺点:消息表会耦合到业务系统中,如果没有封装好的解决方案,会有很多杂活需要处理。

2.4 TCC 事务

TCC 即为 Try Confirm Cancel,它属于补偿型分布式事务,业务层面的分布式事务。其中:

Try:指的是预留,即资源的预留和锁定。
Confirm:确认,其实就是真正的执行提交。
Cancel:撤销,就是回滚、撤销锁定动作。

同样,TCC模型也有一个全局的管理者或协调者角色,用来记录TCC全局事务状态,并提交或回滚事务。

TCC模型的难点在于业务上的定义,对每一个操作都需要定义三个动作分别对应 try-confirm-cancel例如,预留操作,需要明确预留或锁定的业务资源。因此TCC是业务耦合型分布式事务,需要根据特定的场景和业务逻辑来设计相应的操作。另外,确认或撤销操作可能需要重试,因此需要保证操作的幂等。

TCC相较于2PC、3PC,其优点在于可以跨数据库跨业务来实现事务,但缺点也显而易见,就是开发量大,业务耦合度高。

TCC 两阶段提交与 XA 两阶段提交的区别:

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

三、TCC 模式常见问题

TCC分布式事务模式其实属于2PC的一种。其本身仍然存在一些绕不开的问题。

3.1 二阶段幂等

由于网络抖动,分布式事务框架可能会重复调用同一分布式事务中的一个分支事务的二阶段方法(comfirm或cancel)。
所以分支事务的二阶段接口必须要保证幂等性,否则会产生资源的重复使用或重复释放从而影响业务。
对于幂等类型的问题,通常的手段是引入幂等查询。例如,可以通过增加一张事务状态表,包含如下几个关键字段:

1.主事务id
2.分支事务id,与主事务id作为联合主键,唯一标识一笔分支事务。
3.分支事务状态:init(1),confirmed(2),rollbacked(3)

幂等记录的插入时机是参与者的Try 方法,此时的分支事务状态会被初始化为 init。然后当二阶段的 comfirm/canel 执行时会将其状态置为 comfirmed/rollbacked。
当TC重复调用二阶段接口时,参与者会先获取事务状态控制表对应的记录查看其事务状态。如果状态已为终态(confirmed或rollbacked),则直接将结果返回给TC,帮助其推进分布式事务,时序图如下:
在这里插入图片描述

3.2 空回滚

空回滚指的是,在未收到 Try 请求的情况下收到 Cancel 请求

如果不对空回滚加以防范的话,可能会造成资源的无效释放,即在没有预留资源的情况下就释放资源,造成故障。

针对空回滚,使用事务状态控制表同样有效。

当 Try 方法被成功执行后,会插入一条分支事务记录,当后续二阶段的 Cancel 方法执行时,如果记录存在且状态为 INIT,就表示一阶段已成功执行,可以正常执行回滚,释放预留资源;如果记录不存在则表示一阶段未执行,本次为空回滚,不释放任何资源。

一般情况下,是应用是需要允许空回滚的。

3.3 资源悬挂

资源悬挂,意思是一阶段Try 由于网络超时或阻塞等原因,在二阶段Cancel(Try超时事务管理器要Cancel全局事务)之后执行,即 Cancel --> Try,造成服务或资源悬挂。

可以看到,资源悬挂的前提是空回滚。因为一阶段Try超时,事务管理器必须执行回滚操作,这就造成了参与者一定会先收到 Cancel ,即空回滚。

视实际业务场景而定,一般会允许空回滚的情况,但要避免悬挂。可以在空回滚后,向事务状态控制表中插入一条 状态为 ROLLBACKED 的分支事务记录,然后在 Try 的时候要增加对幂等的处理(可以依赖于数据库的唯一约束),这样,由于网络原因而超时的 Try 请求就会自动失败,从而放弃调本次TCC事务。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Seata是一个开源的分布式事务解决方案,它提供了一套简单易用的API,可以帮助解决分布式事务问题。Seata使用了两阶段提交协议(Two-Phase Commit,简称2PC)来确保分布式事务的一致性。它由三个核心组件组成:事务协调器(Transaction Coordinator)、资源管理器(Resource Manager)和事务参与者(Transaction Participant)。 事务协调器负责协调和管理全局事务,它负责事务的发起、提交和回滚操作。资源管理器负责管理分支事务的提交和回滚,它与具体的数据源进行交互。事务参与者是分支事务的参与者,它负责执行具体的业务逻辑操作。 当一个分布式事务开始时,事务协调器会生成一个全局事务ID,并将这个ID传递给各个事务参与者。每个事务参与者都会将这个ID关联到自己的本地事务中。在事务执行过程中,各个事务参与者会将本地事务的操作记录到日志中。当所有的事务参与者都执行完毕后,事务协调器会向各个参与者发送提交或回滚的指令,并根据各个参与者的反馈结果来决定最终的事务提交或回滚。 Seata支持多种应用场景,包括数据库事务、消息事务以及跨多个微服务的分布式事务。它提供了与各种常见的中间件和框架的集成,如MySQL、Oracle、Dubbo、Spring Cloud等,使得在这些环境下使用Seata非常方便。 总而言之,Seata是一个强大的分布式事务解决方案,可以帮助开发人员简化分布式事务的管理和处理,并保证数据的一致性。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值