当前位置: 首页 > 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接口…...

OkHttp 中实现断点续传 demo

在 OkHttp 中实现断点续传主要通过以下步骤完成&#xff0c;核心是利用 HTTP 协议的 Range 请求头指定下载范围&#xff1a; 实现原理 Range 请求头&#xff1a;向服务器请求文件的特定字节范围&#xff08;如 Range: bytes1024-&#xff09; 本地文件记录&#xff1a;保存已…...

Cloudflare 从 Nginx 到 Pingora:性能、效率与安全的全面升级

在互联网的快速发展中&#xff0c;高性能、高效率和高安全性的网络服务成为了各大互联网基础设施提供商的核心追求。Cloudflare 作为全球领先的互联网安全和基础设施公司&#xff0c;近期做出了一个重大技术决策&#xff1a;弃用长期使用的 Nginx&#xff0c;转而采用其内部开发…...

CRMEB 框架中 PHP 上传扩展开发:涵盖本地上传及阿里云 OSS、腾讯云 COS、七牛云

目前已有本地上传、阿里云OSS上传、腾讯云COS上传、七牛云上传扩展 扩展入口文件 文件目录 crmeb\services\upload\Upload.php namespace crmeb\services\upload;use crmeb\basic\BaseManager; use think\facade\Config;/*** Class Upload* package crmeb\services\upload* …...

CVE-2020-17519源码分析与漏洞复现(Flink 任意文件读取)

漏洞概览 漏洞名称&#xff1a;Apache Flink REST API 任意文件读取漏洞CVE编号&#xff1a;CVE-2020-17519CVSS评分&#xff1a;7.5影响版本&#xff1a;Apache Flink 1.11.0、1.11.1、1.11.2修复版本&#xff1a;≥ 1.11.3 或 ≥ 1.12.0漏洞类型&#xff1a;路径遍历&#x…...

Netty从入门到进阶(二)

二、Netty入门 1. 概述 1.1 Netty是什么 Netty is an asynchronous event-driven network application framework for rapid development of maintainable high performance protocol servers & clients. Netty是一个异步的、基于事件驱动的网络应用框架&#xff0c;用于…...

接口自动化测试:HttpRunner基础

相关文档 HttpRunner V3.x中文文档 HttpRunner 用户指南 使用HttpRunner 3.x实现接口自动化测试 HttpRunner介绍 HttpRunner 是一个开源的 API 测试工具&#xff0c;支持 HTTP(S)/HTTP2/WebSocket/RPC 等网络协议&#xff0c;涵盖接口测试、性能测试、数字体验监测等测试类型…...

wpf在image控件上快速显示内存图像

wpf在image控件上快速显示内存图像https://www.cnblogs.com/haodafeng/p/10431387.html 如果你在寻找能够快速在image控件刷新大图像&#xff08;比如分辨率3000*3000的图像&#xff09;的办法&#xff0c;尤其是想把内存中的裸数据&#xff08;只有图像的数据&#xff0c;不包…...

学习一下用鸿蒙​​DevEco Studio HarmonyOS5实现百度地图

在鸿蒙&#xff08;HarmonyOS5&#xff09;中集成百度地图&#xff0c;可以通过以下步骤和技术方案实现。结合鸿蒙的分布式能力和百度地图的API&#xff0c;可以构建跨设备的定位、导航和地图展示功能。 ​​1. 鸿蒙环境准备​​ ​​开发工具​​&#xff1a;下载安装 ​​De…...

土建施工员考试:建筑施工技术重点知识有哪些?

《管理实务》是土建施工员考试中侧重实操应用与管理能力的科目&#xff0c;核心考查施工组织、质量安全、进度成本等现场管理要点。以下是结合考试大纲与高频考点整理的重点内容&#xff0c;附学习方向和应试技巧&#xff1a; 一、施工组织与进度管理 核心目标&#xff1a; 规…...

python打卡第47天

昨天代码中注意力热图的部分顺移至今天 知识点回顾&#xff1a; 热力图 作业&#xff1a;对比不同卷积层热图可视化的结果 def visualize_attention_map(model, test_loader, device, class_names, num_samples3):"""可视化模型的注意力热力图&#xff0c;展示模…...