文件状态:
[√] 草稿
[ ] 正在修改
[ ] 正式发布
文件标识: 技术部
当前版本: V 1.0
作 者: w
完成日期: 2021-04-17

修订历史记录

日期 版本 说明 作者
2021.04.17 对分布式事务进行初始设计 w








1.1分布式事务作用

  1. 随着微服务架构的普及,一个大型业务系统往往由若干个子系统构成,这些子系统又拥有各自独立的数据库。往往一个业务流程需要由多个子系统共同完成,而且这些操作可能需要在一个事务中完成。在微服务系统中,这些业务场景是普遍存在的。此时,我们就需要在数据库之上通过某种手段,实现支持跨数据库的事务支持,

    1.2文档范围

    本文档包含以下几个部分:
    1、 分布式事务设计思想
    2、 分布式事务框架
    3、 分布式事务开发

    1.3读者对象

    本文档主要读者包括:
    1、本系统的系统开发人员:开发人员(了解分布式的设计方案、结合现有系统实现功能)。

2.分布式事务设计思想

2.1 分布式事务解决方案

分布式事务的解决方案有如下几种
(1) 全局事务
全局事务基于DTP模型实现。DTP是由X/Open组织提出的一种分布式事务模型——X/Open Distributed Transaction Processing Reference Model。它规定了要实现分布式事务,需要三种角色
AP:Application 应用系统
它就是我们开发的业务系统,在我们开发的过程中,可以使用资源管理器提供的事务接口来实现分布式事务。
TM:Transaction Manager 事务管理器
事务的实现由事务管理器来完成,它会提供分布式事务的操作接口供我们的业务系统调用。这些接口称为TX接口
RM:Resource Manager 资源管理器
提供数据服务的对象都可以是资源管理器,比如:数据库、消息中间件、缓存等。大部分场景下,数据库即为分布式事务中的资源管理器。
(2) 基于可靠消息服务的分布式事务
这种实现分布式事务的方式需要通过消息中间件来实现。假设有A和B两个系统,分别可以处理任务A和任务B。此时系统A中存在一个业务流程,需要将任务A和任务B在同一个事务中处理。基于消息中间件来实现这种分布式事务流程如下:

上述过程中,如果任务A处理失败,那么需要进入回滚流程,如下图所示
image.png
image.png

(3) 最大努力通知(定期校对)
image.png
(4) TCC(两阶段型、补偿型)
TCC即为Try Confirm Cancel,它属于补偿型分布式事务。顾名思义,TCC实现分布式事务一共有三个步骤:

Try:尝试待执行的业务
这个过程并未执行业务,只是完成所有业务的一致性检查,并预留好执行所需的全部资源
Confirm:执行业务
这个过程真正开始执行业务,由于Try阶段已经完成了一致性检查,因此本过程直接执行,而不做任何检查。并且在执行的过程中,会使用到Try阶段预留的业务资源。
Cancel:取消执行的业务
若业务执行失败,则进入Cancel阶段,它会释放所有占用的业务资源,并回滚Confirm阶段执行的操作。

2.2 基于RocketMq的分布式事务

(1) RocketMq分布式事务的机制

通过消息的异步事务,可以保证本地事务和消息发送同时执行成功或失败,从而保证了数据的最终一致性。
· 发送prepare消息,该消息对Consumer不可见
· 执行本地事务
· 若本地事务执行成功,则向MQ提交消息确认发送指令;若本地事务执行失败,则向MQ发送取消指令
· 若MQ长时间未收到确认发送或取消发送的指令,则向业务系统询问本地事务状态,并做补偿处理
image.png

(2) RocketMq事务消息序列图

image.png

(3)客户端事务消息发送序列图

image.png

3.分布式事务框架

3.1 框架的实现原理

框架实现消息的生产者和消费者,封装了RocketMq的消息发送和接收,对业务只暴露了TransactionListenerInterface和TransactionConsumerInterface接口。业务方不关心具体的中间件RocketMq的细节和调用。

生产者执行第一阶段业务成功后发送消息到RocketMq。消费者接收第一阶段业务发送的消息,执行第二阶段的业务。通过RocketMq的消息完成二阶段的事务提交。

TransactionProducer(生产者)实现了业务的TransactionListenerInterface接口注入,RocketMq的TransactionListener,发送RocketMq消息
TransactionConsumer(消费者)实现了业务的TransactionConsumerInterface接口注入,RocketMq的MessageListenerCurrently,接收RocketMq消息

TransactionListenerInterface 接口,业务只需在该接口的excute方法调用业务方法。框架会自动执行excute方法的业务再发送消息给RocketMq。
TransactionConsumerInterface接口,业务只需在该接口的receiveMsg方法调用业务方法。框架会自动接收RocketMq消息后调用业务方法。

分布式事务的时序图
image.png

4. 分布式事务开发

以分布式事务调用系统A、B为例,完成分布式事务调用,分两步:
1)在系统A实现TransactionListenerInterface接口,完成第一阶段业务
2)在系统B 的com.panpay.bank.XXX.transactio.ConsumeDispatch里添加消费,完成第二阶段业务

4.1 分布式事务的第一阶段业务

(1)在com.panpay.bank.XXX.transaction包里新增实现第一阶段的TransactionListenerInterface接口的文件,excute里调用业务。ResultDTO的success为true,则发送消息到Rocketmq,否则不发送消息到Rocketmq

image.png

(2)在Service或Controller里调用transactionUtil.getInstance().sendMessage

image.png

参数说明:
TransationMessageEnum 里定义消息的tag,用于接收方接收该tag的消息
image.png
TestParse1传递给消费者的消息内容
AAA 用于标注事务的唯一业务key,方便后续查找
testProducer第一阶段的业务生产者接口对象
testReqDTO第一阶段的业务生产者的接口参数

4.2分布式事务的第二阶段业务

(1)在分布式事务的第二阶段业务里增加tag的消费

在com.panpay.bank.XXX.transaction包里ConsumeDispatch里添加tag消费
image.png