一、分布式事务
事务(Transaction),一般是指要做的或所做的事情。在计算机术语中是指访问并可能更新数据库中各种数据项的一个程序执行单元(unit)。事务通常由高级数据库操纵语言或编程语言(如SQL,C++或Java)书写的用户程序的执行所引起,并用形如begin transaction和end transaction语句(或函数调用)来界定。事务由事务开始(begin transaction)和事务结束(end transaction)之间执行的全体操作组成。
摘自百度百科
提到事务我们很容易会想到事务的四大特性ACID,但是在分布式的情况下想实现和单机下一样的事务并不是一件容易的事情,目前一些常见的分布式事务解决方案有如下几种,**消息队列+本地事件表、2PC、3PC、TCC、基于RocketMQ的半消息机制等等。**这些方案都有各自的使用场景,个人理解在高并发的情况下基于RocketMQ的半消息机制来实现分布式事务是一种不错的解决方案,其他的方案例如2PC、3PC或多或少存在锁定资源的情况,所以今天的内容就是介绍以RocketMQ的半消息为基础来实现分布式事务。
二、原理分析
这里借用一下RocketMQ官方的图,从图中可以看出当订单支付后有对应4个分支的操作分别是:更新订单状态、更新物流、更新用户积分、清空购物车。这4个步骤应该在同一个事务中,但是由于分布式的情况通常我们很难做到一致性,所以我们会采用一种折中的手段:最终一致性。接下来我们学习一下如何使用RocketMQ来解决这一问题。
首先在上一篇文章中我们知道了RocketMQ有一种独特的机制,半消息,当消息处于“半事务消息”的状态时,消费者是无法获取到消息的,利用这一特性我们可以轻松的实现分布式事务。

流程如下:1、首先生产者向RocketMQ服务端投递一条半事务消息并等待服务端的响应
2、投递成功则开始执行本地事务(如果失败可以尝试重新投递,如果多次投递失败则需要人工介入)
3、根据本地事务执行的结果来告知RocketMQ服务端是否提交消息,如果执行成功则投递否则回滚
4、RocketMQ服务端将成功的消息投递给消费者,消费者进行消费。
这里需要注意的几点:
1、在断网或者是生产者应用重启的特殊情况下,若服务端未收到发送者提交的二次确认结果,或服务端收到的二次确认结果为Unknown未知状态,经过固定时间后,服务端将对消息生产者即生产者集群中任一生产者实例发起消息回查。
2、消费者端最好对消费做好幂等性处理,防止重复消费。
三、代码演示
1、业务描述
支付成功修改订单流水状态为支付成功,订单修改为已支付。其中订单和支付处于两个微服务中使用不同的数据库。
2、生产者
2.1、依赖
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.rocketmq</groupId>
<artifactId>rocketmq-spring-boot-starter</artifactId>
<version>2.2.2</version></

本文通过RocketMQ的半消息机制实现分布式事务,介绍了其工作原理、代码实现过程及注意事项,适用于对数据一致性要求不高但追求高并发的场景。
最低0.47元/天 解锁文章
4691

被折叠的 条评论
为什么被折叠?



