1 背景
市面上常见的有,2pc/3pc、tcc、saga 等常见的分布式事务解决方案,然而理论施行起来框架比拟重,设计开发比拟繁琐,不易于疾速开发上手。本文提供一种基于柔性事务设计的简略易上手的分布式事务设计方案,用于解决常见的分布式事务常见场景。
2 常见分布式事务场景
2.1 同步场景
常见的场景,办法内依赖内部微服务多个同步接口,等同步接口返回再开展后续逻辑,如下图 1 形容。
图 1 分布式事务同步场景
存在的问题:B/ C 失败后,A/ B 不能回滚,造成数据不统一?
2.2 异步场景
办法内依赖内部微服务多个同步接口同时,本地事务提交并收回异步 MQ,如下图 2 形容。
图 2 分布式事务异步场景
存在的问题:询价零碎无奈保障本地事务和 mq 音讯的发送同时胜利或失败,会造成数据不统一。
3 解决方案
3.1 数据模型设计
事务表:记录每次同步办法执行的状态,包含:1- 进行中(同步办法执行开始)、2- 已实现(同步办法执行胜利)、3- 失败(同步办法执行失败)、4- 已回滚(回滚办法执行胜利);
办法调用表:记录一个残缺的事务内所有办法的执行前入参、同步办法接口、回滚接口、回滚入参、办法执行程序,如下图 3 形容:
图 3 事务服务数据模型
3.2 设计原理
原理:一个残缺事务内,1. 首先每个办法提供回滚接口,其次,事务内每次同步办法执行时,优先保护入参数据到事务表,不便后续做回滚弥补;2. 整个事务内某一个办法执行失败时,完结整个事务,并更新事务表状态 = 失败;3. 事务表通过轮询状态 status=3(失败) 事务,调用回滚接口,利用回滚入参进行接口弥补;4. 回滚逻辑:找到事务表中失败的执行办法的程序值,只调用小于失败程序值的所有回滚接口、入参,留神并不回滚失败值的接口,并依据程序倒序进行接口回滚弥补。
图 4 回滚原理图
3.3 执行时序
图 5 回滚执行时序图
3.4 回滚失败解决计划:
- 事务服务的高可用保障:柔性事务前提是保障事务服务高可用性,重点保障;
- 回滚服务重试机制:回滚接口失败重试机制,保证数据一致性;
- 为了防止架构复杂度,做日志记录、报警、人工解决。
4 留神问题
- 回滚服务的幂等性:回滚做好业务防重和零碎防重,避免因为回滚带来的业务数据不统一;
- 脏数据:整个事务中某一办法执行失败,后面调用办法的数据作为脏数据应用。简略的解决方案:依赖事务表整个事务执行状态来决定是否应用脏数据。但毛病就是这样会耦合业务逻辑;
- 中心化:整个事务的保护齐全依赖事务服务实现,须要保障事务服务的高可用性;
- 实时性:事务保护本计划通过定时工作保护,如果业务场景有实时性要求,形式能够改为:在整个事务中某一办法执行失败时,catch 异样,catch 内更新工作状态胜利时,间接进行回滚逻辑调用。
5 总结
除了通过惯例本地大事务保障事务完整性计划,本次计划提供了一套基于柔性事务回滚弥补的形式来保障分布式事务,通过保护事务服务和事务服务中心对应数据表,从而保障整个分布式事务的完整性。实现形式简略、轻量、易于操作,不便地解决了常见分布式事务场景。
作者:郑朋辉