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

Spring事物

文章目录

  • 为什么需要事务管理?
  • Spring事务的核心概念
    • 1. 事务传播行为
    • 2. 隔离级别
    • 3. 回滚规则
  • 如何配置Spring事务?
    • 使用@Transactional注解
  • 事务失效的常见场景
    • 1. 方法不是public的
    • 2. 同一个类内部方法调用
    • 3. 异常被捕获没抛出
    • 4. 数据库不支持事务
  • 总结

大家好,今天想和大家分享一下Spring框架中的事务管理。这东西在实际开发中超级实用,尤其是处理数据库操作的时候,能帮我们避免很多坑。

为什么需要事务管理?

首先,事务就是一组操作,要么全成功,要么全失败。比如你转账,从A账户扣钱,再给B账户加钱,这两个步骤必须一起完成,要是扣钱成功了加钱失败,那不就乱套了?在Spring里,事务管理主要针对数据库操作,但也能扩展到其他资源。Spring提供了两种方式:编程式事务声明式事务。编程式就是手动写代码控制事务开始、提交、回滚;声明式更方便,通过注解或XML配置,让Spring自动帮你管。

Spring事务的核心概念

1. 事务传播行为

传播行为决定了事务在方法嵌套调用时的行为。Spring定义了7种:

传播行为描述
REQUIRED如果当前有事务,就加入;没有就新建一个。最常用。
REQUIRES_NEW总是新建一个事务,挂起当前事务。
NESTED嵌套事务,类似于REQUIRES_NEW,但回滚时只影响子事务。
SUPPORTS有事务就加入,没有就非事务执行。
MANDATORY必须有事务,否则抛异常。
NOT_SUPPORTED非事务执行,如果有就挂起。
NEVER必须非事务,否则抛异常。

2. 隔离级别

Spring支持数据库的隔离级别:

隔离级别描述
DEFAULT用数据库默认的。
READ_UNCOMMITTED最低级别,可能脏读。
READ_COMMITTED避免脏读,但可能不可重复读。
REPEATABLE_READ避免不可重复读,但可能幻读。
SERIALIZABLE最高级别,完全串行,但性能差。

实际项目中,READ_COMMITTED够用了,除非有特殊需求。

3. 回滚规则

默认情况下,Spring只在RuntimeException时回滚,Checked Exception不会。你可以用@Transactional(rollbackFor = Exception.class)指定回滚的异常类型。

如何配置Spring事务?

Spring Boot时代,配置超级简单。主要用注解方式。

使用@Transactional注解

在Service方法上加:

@Service
public class UserService {@Autowiredprivate UserRepository userRepository;@Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.READ_COMMITTED, rollbackFor = Exception.class)public void transferMoney(Long fromId, Long toId, BigDecimal amount) {User from = userRepository.findById(fromId).orElseThrow();User to = userRepository.findById(toId).orElseThrow();from.setBalance(from.getBalance().subtract(amount));to.setBalance(to.getBalance().add(amount));userRepository.save(from);userRepository.save(to);// 模拟异常int i = 10 / 0;}
}

这个例子中,如果抛异常,整个转账操作都会回滚。

事务失效的常见场景

1. 方法不是public的

Spring的事务是基于AOP代理实现的,默认只对public方法生效。如果你把@Transactional加在protected、private或package-private方法上,事务不会触发。

2. 同一个类内部方法调用

假如类A有方法foo()调用bar(),bar()有@Transactional,但因为没走代理(直接this.bar()),事务不生效。

解决方案

  • 在同一个类中不要用到内部方法调用
  • AopContext.currentProxy()走代理,但需@EnableAspectJAutoProxy(exposeProxy = true)。

3. 异常被捕获没抛出

@Transactional默认只在抛出RuntimeException时回滚。如果你try-catch了异常,没再抛,事务就提交了。

4. 数据库不支持事务

数据库不支持事务:如MyISAM引擎,用InnoDB。

总结

我在这篇文章中分享了Spring事务管理的实用经验,从为什么需要事务入手,解释了它如何确保操作的原子性,比如转账场景。接着,我详细介绍了核心概念,包括传播行为和隔离级别的表格展示,以及回滚规则。然后,我展示了如何用@Transactional注解配置事务,并举了转账代码例子。最后,我列出了事务失效的常见坑,如非public方法和类内调用问题,希望能帮大家在开发中避开雷区,更高效地处理数据库操作。

http://www.xdnf.cn/news/1303075.html

相关文章:

  • 智能座舱软件架构设计的宏观决策框架
  • 【自动驾驶】自动驾驶概述 ② ( 自动驾驶技术路径 | L0 ~ L5 级别自动驾驶 )
  • 数据结构:二叉树的表示方式(Representation of Binary Trees)
  • 【测试工具】JMeter基本使用及MySQL数据库压力测试
  • Baumer高防护相机如何通过YoloV8深度学习模型实现驾驶员疲劳的检测识别(C#代码UI界面版)
  • python的美食交流社区系统
  • @[TOC](计算机是如何⼯作的) JavaEE==网站开发
  • 前端性能优化工具Performance面板实战指南
  • 【swift开发】SwiftUI概述 SwiftUI 全面解析:苹果生态的声明式 UI 革命
  • 【C#补全计划】事件
  • 【2D】圆上数值积分(半径方向用高斯积分减少点数)
  • 综合案例:Python 函数知识整合 — 学生成绩管理系统
  • Python 类(Class)学习
  • 【新手入门】Android基础知识(一):系统架构
  • 【Golang】:流程控制语句
  • 【Vibe Coding 工程之 StockAnalyzerPro 记录】- EP1.先写 PRD
  • 【秋招笔试】2025.08.15饿了么秋招机考-第一题
  • P4069 [SDOI2016] 游戏 Solution
  • 微信小程序 拖拽签章
  • Git版本控制器
  • spring中异步任务注解@Async和@scheduled的使用
  • 2025年机械制造、机器人与计算机工程国际会议(MMRCE 2025)
  • Docker Compose 入门教程
  • MySQL、PolarDB、PolarDB-X、TableStore、MongoDB、TiDB、ClickHouse选型
  • docker入门
  • Java 调用 Python 脚本:实现 HelloWorld
  • 计算机视觉(opencv)实战五——图像平滑处理(均值滤波、方框滤波、高斯滤波、中值滤波)附加:视频逐帧平滑处理
  • 从根本上解决MAC权限问题(关闭sip)
  • SSL和TLS协议的消息认证码(MAC)
  • Android RxJava变换操作符详解