如何在Spring Boot中实现基于消息队列的分布式事务。我们将使用RocketMQ作为消息中间件,因为它提供了完整的事务消息功能,是实现此模式的绝佳选择。
一、核心原理回顾
其核心是保证 “本地事务” 与 “消息发送” 这两个操作的原子性(要么都成功,要么都失败)。RocketMQ的事务消息机制完美解决了这个问题,流程如下:
- 发送半消息(Half Message):消息对消费者不可见。
- 执行本地事务:在应用数据库中执行业务操作。
- 提交/回滚消息:根据本地事务执行结果,通知Broker使消息可见或丢弃。
- 事务回查(Back Check):如果Broker未收到确认,会回查生产者以确认消息最终状态。
二、Spring Boot + RocketMQ 实现步骤
环境准备
- 安装并启动RocketMQ:包括NameServer和Broker。
- 创建Spring Boot项目:使用Spring Initializr创建。
- 添加依赖:在
pom.xml
中添加RocketMQ Starter依赖。
<dependency>
<groupId>org.apache.rocketmq</groupId>
<artifactId>rocketmq-spring-boot-starter</artifactId>
<version>2.3.0</version> <!-- 请使用最新版本 -->
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId> <!-- 或其他数据访问技术 -->
</dependency>
第1步:配置Application.yml
rocketmq:
name-server: 127.0.0.1:9876 # RocketMQ NameServer地址
producer:
group: my-transaction-producer-group # 生产者组名,重要!
spring:
datasource:
url: jdbc:mysql://localhost:3306/your_db?useSSL=false
username: root
password: password
jpa:
hibernate:
ddl-auto: update
show-sql: true
第2步:编写业务场景
我们以一个经典场景为例:用户下单成功后,发送消息通知积分服务增加积分。
- 订单服务 (Producer):负责创建订单(本地事务)和发送事务消息。
- 积分服务 (Consumer):负责消费消息,为用户增加积分。
第3步:实现生产者(订单服务)
a. 定义实体和Repository
@Entity
@Table(name = "t_order")
@Data
public class Order {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String orderSn;
private Long userId;
private BigDecimal amount;
// ... other fields
}
public interface OrderRepository extends JpaRepository<Order, Long> {
}