当前位置: 首页 > news >正文

Spring Boot: 使用 @Transactional 和 TransactionSynchronization 在事务提交后发送消息到 MQ

Spring Boot: 使用 @TransactionalTransactionSynchronization 在事务提交后发送消息到 MQ

在微服务架构中,确保消息的可靠性和一致性非常重要,尤其是在涉及到分布式事务的场景中。本文将演示如何使用 Spring Boot 的事务机制和 TransactionSynchronization 来在事务提交后发送消息到消息队列(MQ)。这样可以保证只有在事务成功提交后,消息才会被发送。

背景

在处理数据更新的同时,我们可能需要将一些数据变更的消息推送到消息队列(例如 RabbitMQ、Kafka)。为了保证数据和消息的一致性,通常需要在事务提交后再发送消息。Spring 的 @Transactional 注解和 TransactionSynchronization 机制非常适合处理这种需求。

我们将通过一个简单的示例,演示如何在事务提交后发送消息。我们将使用 RabbitMQ 作为消息队列,但这个方法可以扩展到其他类型的 MQ。

核心思想

  • 事务同步: 使用 TransactionSynchronizationManager 注册一个事务同步回调,确保消息在事务提交后被发送。
  • afterCommit 回调: 该回调将在事务成功提交后执行,确保只有在数据操作成功时才会发送消息。

步骤概述

  1. 定义一个服务: 使用 @Transactional 注解来确保数据操作在事务中进行。
  2. 注册事务同步回调: 在事务内注册一个同步回调,确保在事务提交后发送消息。
  3. 消息发送: 使用 RabbitTemplate 将消息发送到 RabbitMQ 或其他消息队列。

示例:使用 TransactionSynchronization 在事务提交后发送消息

1. 配置 RabbitMQ

首先,我们需要配置 RabbitMQ 的连接。我们将使用 Spring Boot 提供的 RabbitTemplate 来发送消息。

@Configuration
public class RabbitConfig {@Beanpublic Queue orderQueue() {return new Queue("orderQueue", false);}@Beanpublic RabbitTemplate rabbitTemplate(ConnectionFactory connectionFactory) {return new RabbitTemplate(connectionFactory);}
}
2. 定义业务服务

接下来,我们创建一个业务服务 MyService,它将在事务提交后发送消息到消息队列。在该服务中,我们使用 @Transactional 来管理事务,并通过 TransactionSynchronizationManager.registerSynchronization 注册一个事务同步回调,确保在事务提交成功后才发送消息。

@Service
public class MyService {@Autowiredprivate RabbitTemplate rabbitTemplate;@Transactionalpublic void doSomething() {// 执行一些业务逻辑,例如保存数据库记录System.out.println("Executing business logic...");// 注册事务同步回调TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronization() {@Overridepublic void afterCommit() {// 事务提交后发送 MQ 消息rabbitTemplate.convertAndSend("exchangeName", "routingKey", "Message after commit");System.out.println("Message sent after commit!");}@Overridepublic void beforeCompletion() {// 可选:在事务完成前做一些操作}});}
}
3. 处理事务和消息

doSomething() 方法中,我们进行了数据库操作(模拟的业务逻辑),并注册了一个事务同步回调。这个回调会在事务提交成功后执行,发送一条消息到 RabbitMQ。消息的发送是在事务提交后进行的,因此我们确保了消息与数据的操作一致性。

  • 事务提交后才发送消息: 只有在事务提交成功后,afterCommit 方法中的消息发送操作才会被执行。
  • 失败回滚: 如果事务执行失败,消息不会被发送,因为事务会回滚,afterCommit 方法不会被调用。
4. 控制事务提交和回滚

你可以在业务逻辑中使用 @Transactional 注解来管理事务。当事务提交时,注册的同步回调将被触发,从而发送消息。示例如下:

@RestController
@RequestMapping("/orders")
public class OrderController {@Autowiredprivate MyService myService;@PostMapping("/create")public ResponseEntity<String> createOrder(@RequestBody Order order) {try {myService.doSomething();return ResponseEntity.ok("Order processed successfully");} catch (Exception e) {return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("Order processing failed");}}
}

扩展:多个事务提交,多个不同消息的例子

假设我们需要在一个方法中处理多个不同类型的事务,并根据不同的条件发送不同的消息。我们可以扩展上述示例,实现多个事务和不同消息发送。

@Service
public class MyService {@Autowiredprivate RabbitTemplate rabbitTemplate;@Transactionalpublic void doSomethingMultipleOrders(Order order1, Order order2) {// 处理订单1System.out.println("Processing order 1...");// 注册事务同步回调,发送订单1的消息TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronization() {@Overridepublic void afterCommit() {rabbitTemplate.convertAndSend("exchangeName", "routingKey1", "Order 1 message after commit");System.out.println("Order 1 message sent after commit!");}});// 处理订单2System.out.println("Processing order 2...");// 注册事务同步回调,发送订单2的消息TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronization() {@Overridepublic void afterCommit() {rabbitTemplate.convertAndSend("exchangeName", "routingKey2", "Order 2 message after commit");System.out.println("Order 2 message sent after commit!");}});}
}

在上面的代码中,我们为两个订单分别注册了事务同步回调。每个回调在事务提交后发送不同的消息。这可以扩展为多个事务提交,针对每个不同的事务执行不同的消息发送操作。

总结

通过使用 Spring 的 @Transactional 注解和 TransactionSynchronizationManager,我们可以确保只有在事务提交后才会发送消息。这个方法可以用于各种 MQ 实现(如 RabbitMQ、Kafka),并且能保证事务和消息的顺序一致性。在实际应用中,这种方法可以帮助我们有效避免消息丢失和数据不一致的问题。

希望本篇博客能够帮助你理解如何在 Spring Boot 中使用事务机制来确保在事务提交后发送消息,并且能够处理多个事务和多个消息的情况。

相关文章:

Spring Boot: 使用 @Transactional 和 TransactionSynchronization 在事务提交后发送消息到 MQ

Spring Boot: 使用 Transactional 和 TransactionSynchronization 在事务提交后发送消息到 MQ 在微服务架构中&#xff0c;确保消息的可靠性和一致性非常重要&#xff0c;尤其是在涉及到分布式事务的场景中。本文将演示如何使用 Spring Boot 的事务机制和 TransactionSynchron…...

LQB(2)-python-枚举

前言 python中的枚举一般有两个说法&#xff0c;一个是枚举算法&#xff08;暴力求解法&#xff0c;算法层面&#xff09;&#xff0c;一个是遍历使用enumerate()函数或者enum模块创建&#xff08;&#xff09;。 暴力求解法在之前的博文里面讲过了&#x1f447;&#xff0c;…...

MongoDB开发规范

分级名称定义P0核心系统需7*24不间断运行&#xff0c;一旦发生不可用&#xff0c;会直接影响核心业务的连续性&#xff0c;或影响公司名誉、品牌、集团战略、营销计划等&#xff0c;可能会造成P0-P2级事故发生。P1次核心系统这些系统降级或不可用&#xff0c;会间接影响用户使用…...

为什么DeepSeek服务器繁忙?

致敬DeepSeek 用户层面 用户数量激增&#xff1a;DeepSeek 免费且功能强大&#xff0c;对普通用户和开发者都极具吸引力124。尤其是在新功能推出、新模型上线或相关热门活动期间&#xff0c;大量用户会在短时间内涌入9。例如春节期间&#xff0c;DeepSeek 的用户量达到四千万7。…...

律所录音证据归集工具:基于PyQt6与多线程的自动化音频管理解决方案

在律所日常工作中&#xff0c;音频证据的整理与归集是一个高频且复杂的任务。面对大量的案件录音文件&#xff0c;如何实现快速且准确的分类与存档&#xff0c;成为了律所提高效率、降低出错率的关键。本文将通过技术角度解析一款名为律所录音证据归集工具的项目&#xff0c;详…...

【含开题报告+文档+PPT+源码】基于SpringBoot+Vue旅游管理网站

开题报告 本论文探讨了一款采用现代Web开发技术构建的台州市旅游综合信息与服务平台的设计与实现。该系统基于SpringBoot框架&#xff0c;以其轻量级、快速开发和强大的企业级应用支持能力为核心后端技术支撑&#xff0c;结合Vue.js前端框架及ElementUI组件库&#xff0c;为用…...

unity碰撞的监测和监听

1.创建一个地面 2.去资源商店下载一个火焰素材 3.把procedural fire导入到自己的项目包管理器中 4.给magic fire 0 挂在碰撞组件Rigidbody , Sphere Collider 5.创建脚本test 并挂在magic fire 0 脚本代码 using System.Collections; using System.Collections.Generic; usi…...

DeepSeek-R1 32B Windows+docker本地部署

最近国产大模型DeepSeek兴起&#xff0c;本地部署了一套deepseek同时集成Open WebUI界面,给大家出一期教程。 软件&#xff1a;Ollama、docker、Open WebUI 一、用Ollama下载模型 首先我们需要安装Ollama&#xff0c;它可以在本地运行和管理大模型。 到Ollama官网 https://ol…...

C++11新特性之unique_ptr智能指针

本节继续介绍智能指针&#xff0c;不了解的读者可以先阅读——C11新特性之shared_ptr智能指针-CSDN博客 1.介绍 unique_ptr是C11标准提供的另一种智能指针。与shared_ptr不同的是&#xff0c;unique_ptr指针指向的堆内存无法同其他unique_ptr共享&#xff0c;也就是每一片堆内…...

Vue与Konva:解锁Canvas绘图的无限可能

前言 在现代Web开发中&#xff0c;动态、交互式的图形界面已成为提升用户体验的关键要素。Vue.js&#xff0c;作为一款轻量级且高效的前端框架&#xff0c;凭借其响应式数据绑定和组件化开发模式&#xff0c;赢得了众多开发者的青睐。而当Vue.js邂逅Konva.js&#xff0c;两者结…...

python绘图之柱状堆积图的绘制

本节来学习用python来绘制柱状堆积图. 使用的库为matplotlib.pyplot,numpy 代码如下 # 导入必要的库 import matplotlib.pyplot as plt # 用于绘图 import numpy as np # 用于数值计算# 模拟一些数据 x [数值{}.format(i) for i in range(10)] # 创建一个包含10个元素的列…...

剪辑学习整理

文章目录 1. 剪辑介绍 1. 剪辑介绍 剪辑可以干什么&#xff1f;剪辑分为哪些种类&#xff1f; https://www.bilibili.com/video/BV15r421p7aF/?spm_id_from333.337.search-card.all.click&vd_source5534adbd427e3b01c725714cd93961af 学完剪辑之后如何找工作or兼职&#…...

DeepSeek从入门到精通:全面掌握AI大模型的核心能力

文章目录 一、DeepSeek是什么&#xff1f;性能对齐OpenAI-o1正式版 二、Deepseek可以做什么&#xff1f;能力图谱文本生成自然语言理解与分析编程与代码相关常规绘图 三、如何使用DeepSeek&#xff1f;四、DeepSeek从入门到精通推理模型推理大模型非推理大模型 快思慢想&#x…...

AI大模型训练实战:分布式与微调指南

AI大模型训练实战:分布式与微调指南 适用人群:有一定深度学习基础,正在或即将参与大模型(如 GPT、DeepSeek 等)训练与部署的工程师、研究者;想要理解分布式策略与微调方法的读者。 一、大模型为何需要分布式与微调? 随着 GPT、DeepSeek 等大模型参数规模攀升至数十亿甚…...

整合 Redis 分布式锁:从数据结构到缓存问题解决方案

引言 在现代分布式系统中&#xff0c;Redis 作为高性能的键值存储系统&#xff0c;广泛应用于缓存、消息队列、实时计数器等多种场景。然而&#xff0c;在高并发和分布式环境下&#xff0c;如何有效地管理和控制资源访问成为一个关键问题。Redis 分布式锁正是为了解决这一问题…...

并查集题目

并查集题目 聚合一块&#xff08;蓝桥&#xff09;合根植物&#xff08;蓝桥&#xff09;等式方程的可满足性省份数量 并查集&#xff08;Union-Find&#xff09;算法是一个专门针对「动态连通性」的算法。双方向的连通。 模板&#xff1a; class UF {// 连通分量个数private …...

日志2025.2.9

日志2025.2.9 1.增加了敌人挥砍类型 2.增加了敌人的死亡状态 在敌人身上添加Ragdoll&#xff0c;死后激活布偶模式 public class EnemyRagdoll : MonoBehaviour { private Rigidbody[] rigidbodies; private Collider[] colliders; private void Awake() { rigidbodi…...

支持多种网络数据库格式的自动化转换工具——VisualXML

一、VisualXML软件介绍 对于DBC、ARXML……文件的编辑、修改等繁琐操作&#xff0c;WINDHILL风丘科技开发的总线设计工具——VisualXML&#xff0c;可轻松解决这一问题&#xff0c;提升工作效率。 VisualXML是一个强大且基于Excel表格生成多种网络数据库文件的转换工具&#…...

Java并发编程笔记

Java并发基础知识补全 启动 启动线程的方式只有&#xff1a; 1、X extends Thread;&#xff0c;然后X.start 2、X implements Runnable&#xff1b;然后交给Thread运行 线程的状态 Java中线程的状态分为6种&#xff1a; 1. 初始(NEW)&#xff1a;新创建了一个线程对象&…...

大语言模型实践——基于现有API的二次开发

基于现有的API平台做一些实用的AI小应用。 API服务商&#xff1a;阿里云百炼 云服务器&#xff1a;阿里云&#xff08;2核2GB&#xff09; 部署框架&#xff1a;gradio 调用框架&#xff1a;openai 语言&#xff1a;Python &#xff08;注&#xff1a;若搭建网站或API接口…...

【大模型RAG】拍照搜题技术架构速览:三层管道、两级检索、兜底大模型

摘要 拍照搜题系统采用“三层管道&#xff08;多模态 OCR → 语义检索 → 答案渲染&#xff09;、两级检索&#xff08;倒排 BM25 向量 HNSW&#xff09;并以大语言模型兜底”的整体框架&#xff1a; 多模态 OCR 层 将题目图片经过超分、去噪、倾斜校正后&#xff0c;分别用…...

谷歌浏览器插件

项目中有时候会用到插件 sync-cookie-extension1.0.0&#xff1a;开发环境同步测试 cookie 至 localhost&#xff0c;便于本地请求服务携带 cookie 参考地址&#xff1a;https://juejin.cn/post/7139354571712757767 里面有源码下载下来&#xff0c;加在到扩展即可使用FeHelp…...

工业安全零事故的智能守护者:一体化AI智能安防平台

前言&#xff1a; 通过AI视觉技术&#xff0c;为船厂提供全面的安全监控解决方案&#xff0c;涵盖交通违规检测、起重机轨道安全、非法入侵检测、盗窃防范、安全规范执行监控等多个方面&#xff0c;能够实现对应负责人反馈机制&#xff0c;并最终实现数据的统计报表。提升船厂…...

k8s从入门到放弃之Ingress七层负载

k8s从入门到放弃之Ingress七层负载 在Kubernetes&#xff08;简称K8s&#xff09;中&#xff0c;Ingress是一个API对象&#xff0c;它允许你定义如何从集群外部访问集群内部的服务。Ingress可以提供负载均衡、SSL终结和基于名称的虚拟主机等功能。通过Ingress&#xff0c;你可…...

关于nvm与node.js

1 安装nvm 安装过程中手动修改 nvm的安装路径&#xff0c; 以及修改 通过nvm安装node后正在使用的node的存放目录【这句话可能难以理解&#xff0c;但接着往下看你就了然了】 2 修改nvm中settings.txt文件配置 nvm安装成功后&#xff0c;通常在该文件中会出现以下配置&…...

定时器任务——若依源码分析

分析util包下面的工具类schedule utils&#xff1a; ScheduleUtils 是若依中用于与 Quartz 框架交互的工具类&#xff0c;封装了定时任务的 创建、更新、暂停、删除等核心逻辑。 createScheduleJob createScheduleJob 用于将任务注册到 Quartz&#xff0c;先构建任务的 JobD…...

Python爬虫(二):爬虫完整流程

爬虫完整流程详解&#xff08;7大核心步骤实战技巧&#xff09; 一、爬虫完整工作流程 以下是爬虫开发的完整流程&#xff0c;我将结合具体技术点和实战经验展开说明&#xff1a; 1. 目标分析与前期准备 网站技术分析&#xff1a; 使用浏览器开发者工具&#xff08;F12&…...

数据链路层的主要功能是什么

数据链路层&#xff08;OSI模型第2层&#xff09;的核心功能是在相邻网络节点&#xff08;如交换机、主机&#xff09;间提供可靠的数据帧传输服务&#xff0c;主要职责包括&#xff1a; &#x1f511; 核心功能详解&#xff1a; 帧封装与解封装 封装&#xff1a; 将网络层下发…...

【服务器压力测试】本地PC电脑作为服务器运行时出现卡顿和资源紧张(Windows/Linux)

要让本地PC电脑作为服务器运行时出现卡顿和资源紧张的情况&#xff0c;可以通过以下几种方式模拟或触发&#xff1a; 1. 增加CPU负载 运行大量计算密集型任务&#xff0c;例如&#xff1a; 使用多线程循环执行复杂计算&#xff08;如数学运算、加密解密等&#xff09;。运行图…...

鱼香ros docker配置镜像报错:https://registry-1.docker.io/v2/

使用鱼香ros一件安装docker时的https://registry-1.docker.io/v2/问题 一键安装指令 wget http://fishros.com/install -O fishros && . fishros出现问题&#xff1a;docker pull 失败 网络不同&#xff0c;需要使用镜像源 按照如下步骤操作 sudo vi /etc/docker/dae…...