Spring Cloud微服务系统基于Rocketmq可靠消息最终一致性实现分布式事务

本文介绍了如何通过安装和配置Rocketmq服务器,结合Spring Cloud微服务,利用Rocketmq的事务消息特性实现分布式事务的一致性。首先详细阐述了Rocketmq服务器的单机和双主双从集群搭建过程,然后讲解了基于Rocketmq的分布式事务方案原理。接下来,通过实例展示了在订单项目中如何导入和配置Rocketmq,包括添加事务状态表、设计TxMapper接口以及处理Json工具。最后,讨论了如何废弃原有业务类并引入新类以适应新的事务处理需求。
摘要由CSDN通过智能技术生成

安装搭建 Rocketmq 服务器

搭建单机 Rocketmq 服务器笔记:

RocketMQ (一) 安装_wanght笔记-CSDN博客_rocketmq zip安装

搭建双主双从同步复制 Rocketmq 服务器笔记:
RocketMQ (二) 双主双从同步复制集群方案

基于 Rocketmq 可靠消息的分布式事务方案原理

Rocketmq事务消息笔记:
RocketMQ 发送事务消息原理分析和代码实现

导入订单项目,无事务版本


 







下载项目代码

  1. 访问 git 仓库 王海涛/seata-samples
  2. 访问项目标签

a

 下载无事务版a

解压到 rocketmq-dtx 目录

压缩文件中的 7 个项目目录解压缩到 rocketmq-dtx 目录

a

导入项目

在 idea 中按两下 shift 键,搜索 add maven projects,打开 maven 工具:

a

然后选择 rocketmq-dtx 工程目录下的 7 个项目的 pom.xml 导入:

a

 启动 Rocketmq

cd /usr/local/rocketmq/  nohup sh bin/mqnamesrv &  nohup sh bin/mqbroker -n localhost:9876 &  
如果需要从配置文件启动 broker: nohup sh bin/mqbroker -n localhost:9876 -c conf/broker.conf &  cd ~/  nohup java -jar rocketmq-console-ng-1.0.1.jar --server.port=8080 --rocketmq.config.namesrvAddr=localhost:9876 &  jps  54801 NamesrvStartup 56038 BrokerStartup 64331 jar

在用户和账户上的父类添加依赖

<!--        添加rocketmq依赖-->
        <dependency>
            <groupId>org.apache.rocketmq</groupId>
            <artifactId>rocketmq-spring-boot-starter</artifactId>
            <version>2.1.0</version>
        </dependency>

订单的application里添加rocketmq里的映

rocketmq:
  name-server: 192.168.64.141:9876  #
  producer:
    group: order-producer

order 添加事务状态表
Rocketmq收到事务消息后,会等待生产者提交或回滚该消息。如果无法得到生产者的提交或回滚指令,则会主动向生产者询问消息状态,称为回查。

在 order 项目中,为了让Rocketmq可以回查到事务的状态,需要记录事务的状态,所以我们添加一个事务的状态表来记录事务状态。

修改 db-init 项目中的 order.sql 文件,创建 tx_table 表:
 

CREATE TABLE tx_table(
	`xid` char(32) PRIMARY KEY COMMENT '事务id',
	`status` int COMMENT '0-提交,1-回滚,2-未知',
	`created_at` BIGINT UNSIGNED NOT NULL COMMENT '创建时间'
);

 上数据库的的代码复制到我截图的地方

然后重新初始化数据库

重新启动 bd-init就行了

添加 TxMapper 访问事务状态表
事务状态保存到 tx_table 表,在 TxMapper 接口和 TxMapper.xml 中添加事务状态数据的读写方法。

本地事务执行后要保存事务信息(事务id、事务状态)到数据库,以便之后进行事务回查,首先创建封装事务信息的类 TxInfo :
 

package cn.tedu.order.entity;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@NoArgsConstructor
@AllArgsConstructor
public class TxInfo {

    private String xid;  //事务id
    private Integer status;  //状态,0成功,1失败
    private Long created; //创建时间

}

TxMapper 接口:

package cn.tedu.order.mapper;

import cn.tedu.order.entity.TxInfo;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;

public interface TxMapper extends BaseMapper<TxInfo> {
    //保存事务状态,insert()  通用mapper里自动生成这个,所以不用写
    //查询事务状态,selectById
    
}

TxMapper.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="cn.tedu.order.mapper.TxMapper" >
    <resultMap id="BaseResultMap" type="cn.tedu.order.entity.TxInfo" >
        <id column="xid" property="xid" jdbcType="CHAR" />
        <result column="created_at" property="created" jdbcType="BIGINT" />
        <result column="status" property="status" jdbcType="INTEGER"/>
    </resultMap>

    <insert id="insert">
        INSERT INTO `tx_table`(`xid`,`created_at`,`status`) VALUES(#{xid},#{created},#{status});
    </insert>
    <select id="selectById" resultMap="BaseResultMap">
        SELECT `xid`,`created_at`,`status` FROM tx_table WHERE xid=#{xid};
    </select>
</mapper>

添加

AccountMessage 类
package cn.tedu.order.entity;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import javax.validation.constraints.NegativeOrZero;
import java.math.BigDecimal;

/**
 * 封装发
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值