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

Spring事务回滚在系统中的应用

以文章发布为例,介绍Spring事务回滚在系统中的应用

事务回滚的核心概念

事务回滚是数据库管理系统中的关键机制,它确保数据库操作要么全部成功,要么全部失败。在Spring框架中,我们可以通过@Transactional注解轻松实现事务管理。

事务的ACID特性

  • 原子性(Atomicity):操作不可分割,要么全部完成,要么全部不执行
  • 一致性(Consistency):事务前后数据库状态保持一致
  • 隔离性(Isolation):并发事务互不干扰
  • 持久性(Durability):事务完成后结果永久保存

文章发布系统的事务应用

在我们的文章发布系统中,存在两种业务场景:

  1. 正式发布:所有操作(主表、文件、白名单)必须全部成功
  2. 草稿保存:主表必须成功,其他操作尽量完成但不强制

事务控制实现代码

@Transactional(rollbackFor = Exception.class)
public RestResponse publishArticle(PublishArticleRequest request) {boolean isDraft = request.getIsDraft() == 2;try {// 设置默认值request.setIsDelete(1);// ...其他默认值设置// 保存文章主表int articleId = userArticlesMapper.publishArticle(request);// 尝试保存附加数据saveAdditionalData(request, articleId, isDraft);return RestResponse.success(isDraft ? "草稿保存成功" : "发布成功");} catch (Exception e) {// 手动标记回滚TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();return RestResponse.fail(isDraft ? "草稿保存失败" : "发布失败");}
}private void saveAdditionalData(PublishArticleRequest request, int articleId, boolean isDraft) {try {// 1. 保存可见白名单if (request.getWatchPermission() == 4) {// ...构建白名单数据userArticlesMapper.publishWatchPermissionnList(watchList);}// 2. 保存评价白名单if (request.getEvaluatePermission() == 4) {// ...构建评价白名单数据userArticlesMapper.publishEvaluatePermissionnList(evaluateList);}// 3. 批量保存文件(性能优化关键)if (request.getFiles() != null && !request.getFiles().isEmpty()) {List<BaseUserArticlesFiles> fileList = request.getFiles().stream().map(fileUrl -> new BaseUserArticlesFiles(articleId, fileUrl)).collect(Collectors.toList());userArticlesMapper.batchInsertFiles(fileList);}} catch (Exception e) {if (isDraft) {// 草稿模式:只记录日志,不抛出异常log.warn("草稿附加数据保存失败(不影响主表)", e);} else {// 发布模式:抛出异常触发事务回滚throw e;}}
}

实体类优化支持批量操作

@Data
public class BaseUserArticlesFiles {@Id@GeneratedValue(strategy = GenerationType.IDENTITY)private Integer id;private Integer userArticlesId;private Integer isDelete = 1; // 默认值private String fileUrl;// 支持批量插入的构造方法public BaseUserArticlesFiles(Integer userArticlesId, String fileUrl) {this.userArticlesId = userArticlesId;this.fileUrl = fileUrl;}
}

MyBatis批量插入实现

<!-- 批量插入文件 -->
<insert id="batchInsertFiles" parameterType="list">INSERT INTO base_user_articles_files (user_articles_id, file_url, is_delete)VALUES<foreach collection="fileList" item="file" separator=",">(#{file.userArticlesId}, #{file.fileUrl}, #{file.isDelete})</foreach>
</insert>

事务回滚的工作原理

在这里插入图片描述

性能优化:批量操作

在文件保存场景中,使用批量插入显著提升性能:

// 普通单条插入(N+1问题)
for (String file : files) {mapper.insertFile(new File(articleId, file));
}// 批量插入(高效)
List<File> fileList = files.stream().map(file -> new File(articleId, file)).collect(Collectors.toList());
mapper.batchInsertFiles(fileList);
http://www.lryc.cn/news/2404257.html

相关文章:

  • .Net Framework 4/C# 属性和方法
  • ASP.NET Core使用Quartz部署到IIS资源自动被回收解决方案
  • Fullstack 面试复习笔记:Spring / Spring Boot / Spring Data / Security 整理
  • 调用.net DLL让CANoe自动识别串口号
  • 第5章:Cypher查询语言进阶
  • 【Python进阶】元类编程
  • 算法(蓝桥杯学习C/C++版)
  • Docker镜像无法拉取问题解决办法
  • ZephyrOS 嵌入式开发Black Pill V1.2之Debug调试器
  • # 主流大语言模型安全性测试(二):英文越狱提示词下的表现与分析
  • SAP 在 AI 与数据统一平台上的战略转向
  • 服务器磁盘空间被Docker容器日志占满处理方法
  • c++学习-this指针
  • 交易所系统攻坚:高并发撮合引擎与合规化金融架构设计
  • OpenCV计算机视觉实战(10)——形态学操作详解
  • libiec61850 mms协议异步模式
  • [论文阅读] 人工智能 | 利用负信号蒸馏:用REDI框架提升LLM推理能力
  • 基于 NXP + FPGA+Debian 高可靠性工业控制器解决方案
  • CSS 选择器全解析:分组选择器/嵌套选择器,从基础到高级
  • uniapp 对接腾讯云IM群公告功能
  • 垂起固定翼无人机应用及技术分析
  • Python Robot Framework【自动化测试框架】简介
  • vite配置@别名,以及如何让IDE智能提示路经
  • c#bitconverter操作,不同变量类型转byte数组
  • 【Linux】LInux下第一个程序:进度条
  • RPA+AI:自动化办公机器人开发指南
  • daz3d + PBRSkin (MDL)+ SSS
  • 计算矩阵A和B的乘积
  • Houdini POP入门学习05 - 物理属性
  • 每日Prompt:双重曝光