个人项目经验-分布式事务

事务特性:

为了提升分布式事务场景下的交易吞吐量,我们自研了分布式事务管理方案,我们实现的分布式事务特性如下:

1、无需单独部署额外的分布式Server服务,只需要引入依赖jar包,避免远程通信,提升性能;

2、代码低侵入,业务只需要声明对应组合服务注解,原子引用注解即可开启全局分布式事务;

3、保证弱一致性,实现分布式事务的最终一致性;

4、支持即时补偿、异步补偿、人工补偿等多种补偿方式;

5、支持SAGA模式;

6、解决空回滚、幂等、防悬挂等问题;

7、支持非关键节点失败后的向前正向提交、反向补偿等两种事务执行形式;

事务架构:

架构图中涉及到的模块:

1、分布式事务核心模块,SAGA模式。负责全局事务的处理;

2、事务日志存储模块,存储事务相关的日志信息;

3、事务监控模块,对事务进行埋点,对事务相关的指标进行监控;

4、事务异常处理模块,当事务遇到异常时进行处理;

5、事务补偿模块,执行即时补偿和异步补偿;

联机交易框架将交易分成两个维度;原子交易(也叫原子服务)与组合交易(也叫组合服务),组合交易由多个原子交易组成。

在组合交易(也叫组合服务)的分布式事务,会存在三种角色:

  • 组合交易为事务发起者;

  • 原子交易为事务的参与者;

  • 联机框架本身为事务的协调器;

作为事务协调器,联机框架主要有以下几种职责:

1、 记录组合交易的事务状态

2、记录原子交易的执行流水;

3、完成事务的正向提交、事务表的状态更新;

4、异常时的回滚操作;

事务管理需要存储事务相关的日志,主要涉及到几张数据表:

1、tsf_compose_txn_log,全局事务信息表,记录组合交易的事务信息,跟踪组合交易的事务状态;

2、tsf_atomic_run_log,记录原子交易的执行流水,用于在事务需要回滚时,根据流水进行回滚;

3、tsf_branch_status,用于记录子交易的事务状态,用于处理空回滚、悬挂、幂等问题;

4、tsf_register_book,事务补偿登记簿,用于进行事务的异步补偿;

ER图:

事务处理流程:

当发起组合交易时,如果打开了分布式事务开关,就会自动开启分布式事务管理,流程如下:

1、框架自动生成核心流水号,记录全局事务信息,并初始化事务状态;

2、原子交易代理在调用原子交易时,首先记录原子交易执行流水,初始化流水状态;

3、如原子交易成功,更新原子交易执行流水状态为已提交,并开始执行下一个子节点,重复步骤2;

4、原子交易全部执行成功后,更新全局事务信息表中的事务状态为已提交,全局事务结束。如其中某个原子交易执行失败,则接着走到第5步;

5、如其中原子交易执行失败,则开始执行即时补偿操作;

6、框架自动根据核心流水号获取组合交易的所有原子交易执行流水,并按照正向执行步骤逆序排序;

7、对于所有原子交易执行流水,调用相应的补偿接口,完成补偿操作;

8、如所有原子交易补偿成功,更新全局事务信息表状态为已回滚,流程结束。如某个原子交易补偿失败,则接着走到第9步;

9、将补偿失败的全局事务信息登记到事务补偿登记簿,待后续执行异步补偿操作;

10、定时任务每隔一段时间,会自动抽取过去失败的一定数量的事务信息,执行异步补偿;

11、如某条事务补偿失败重试达到一定次数,需要人工介入,执行手动补偿;

联机框架解决的主要问题:

1、如何保持事务的幂等性?

一个全局事务使用核心流水号作为主键,保证了全局的唯一性;

一个全局事务中的原子交易通过核心流水号+执行序号保证唯一性;

2、如何防止事务的空回滚?

空回滚指的是,在子事务未提交前,先执行了补偿操作。框架如果在执行补偿时发现没有找到要补偿的核心流水号主键时,会自动返回补偿成功并将原业务主键记录下来,但实际上并不会执行任何补偿逻辑;

3、如何防悬挂?

悬挂是相对于空回滚出现的。补偿已经执行了,又收到了提交请求。此时框架会检查当前核心流水号主键是否已经在空回滚记录下来的核心流水号中存在,如果存在,则不会执行子事务的提交。

4、事务出现异常时,如果不想直接回滚或者遇到回滚一直失败时,是否可以直接重做?

支持,业务在开发组合交易时,可为原子交易配置是否为关键节点,如果关键节点已经执行成功,其他节点失败时,可继续重复执行其他节点,直到成功为止。

--------EOF---------
微信分享/微信扫码阅读