Spring事务

Spring 事务是业务开发的基石,所有支付、订单、库存、对账系统都依赖事务保证数据一致性。本文系统性梳理Spring 事务底层执行流程、两种事务实现方式、优缺点与适用场景、7种传播机制、5种隔离级别,内容精炼、无废话、适合面试背诵 + 生产落地。

一、Spring 事务核心底层执行逻辑

1.1 核心本质

Spring 事务底层基于 AOP 动态代理 实现,属于典型的横切逻辑增强:不修改业务代码,通过代理环绕实现事务的开启、提交、回滚。

1.2 完整执行流程(必考)

  1. 代理拦截 :调用带有 @Transactional 的方法时,Spring 代理拦截请求。

  2. 事务判断:根据当前线程是否存在事务、传播级别判断是否需要新建事务。

  3. 开启事务:获取数据库连接、关闭自动提交(autoCommit=false)。

  4. 执行目标业务方法:执行数据库增删改逻辑。

  5. 正常返回 :无异常 → 手动提交事务、释放连接。

  6. 抛出异常 :命中回滚规则 → 事务回滚,杜绝脏数据。

核心前提 :Spring 事务仅对 public 方法、外部调用、代理对象调用 生效。

二、Spring 两种事务实现方式

2.1 编程式事务(手动编码)

通过 TransactionTemplate 手动编写事务逻辑,全程手动控制开启、提交、回滚。

示例

复制代码
transactionTemplate.execute(status -> {
    // 业务数据库操作
    try {
        // 增删改逻辑
    } catch (Exception e) {
        status.setRollbackOnly();
    }
    return null;
});
优点
  • 细粒度极高,可以精准控制某段代码事务

  • 无 AOP 失效问题,执行稳定可靠

  • 灵活度高,可动态控制事务规则

缺点
  • 代码侵入性极强,冗余代码多

  • 每个业务都要写事务模板,开发效率低

适用场景

复杂动态事务、特殊片段事务、框架注解事务无法满足的极端场景。

2.2 声明式事务(注解事务 @Transactional)------主流

基于 AOP 实现,通过 @Transactional 注解声明事务,无需手动写事务代码。

优点
  • 零侵入:业务代码干净,符合开闭原则

  • 配置简单、统一规范、维护成本低

  • 全局统一管控,适合绝大多数业务场景

缺点
  • 基于 AOP 代理,存在大量事务失效场景

  • 粒度较粗,默认作用于整个方法

  • 隐式执行,排查问题难度高于手动事务

适用场景

95% 以上常规业务:订单、支付、库存、账务、CRUD 业务,是企业开发标准方案。

三、Spring 事务传播机制(7种传播级别)

传播机制核心作用 :解决多个事务方法嵌套调用时,事务如何传递、是否共用、是否新建 的问题。

分为三类:支持当前事务、不支持事务、嵌套事务。

3.1 支持当前事务(常用)

1. REQUIRED(默认)

有事务就加入,无事务就新建。Spring 默认级别,最常用。

  • 外层有事务:内外合并为同一个事务,一滚全滚

  • 外层无事务:自己新建独立事务

2. SUPPORTS

有事务就加入,无事务就非事务运行。

3. MANDATORY

强制要求在事务内运行,外层无事务直接抛异常。

3.2 不支持当前事务

4. REQUIRES_NEW

无论外层是否有事务,始终新建独立事务,内外事务相互独立、互不影响。

外层回滚不影响内层,内层异常也不影响外层(独立提交/回滚)。

5. NOT_SUPPORTED

始终以非事务方式执行,挂起外层事务。

6. NEVER

强制非事务运行,检测到外层有事务直接报错。

3.3 嵌套事务(特殊)

7. NESTED

外层有事务:嵌套在当前事务中,存在独立保存点。

  • 内层异常可单独回滚,不影响外层

  • 外层异常,内层必须全部回滚

外层无事务:新建事务(类似 REQUIRED)

注意:仅支持 MySQL、JDBC,不支持分布式事务。

四、事务隔离级别(5种)

隔离级别用来解决并发事务引发的脏读、不可重复读、幻读问题,是数据库并发控制核心。

三大并发问题(由差到优):

  • 脏读 :一个事务读到另一个事务未提交的脏数据

  • 不可重复读:同一事务内,两次查询结果不一致(被其他事务 update)

  • 幻读:同一事务内,两次查询行数不一致(被其他事务 insert/delete)

4.1 五种隔离级别详解

1. DEFAULT(Spring 默认)

跟随数据库默认隔离级别。MySQL 默认 RR(可重复读)。

2. READ_UNCOMMITTED(读未提交)

最低级别,可读到未提交数据。脏读、不可重复读、幻读全部存在,生产几乎不用。

3. READ_COMMITTED(读已提交 / RC)

只能读取已提交数据。

  • 解决:脏读

  • 存在:不可重复读、幻读

Oracle 默认隔离级别。

4. REPEATABLE_READ(可重复读 / RR,MySQL默认)

保证同一事务多次读取数据一致。

  • 解决:脏读、不可重复读

  • 存在:幻读(MySQL 通过间隙锁极大缓解,但未彻底解决)

5. SERIALIZABLE(串行化)

最高级别,事务串行执行,彻底解决三大问题。

缺点:性能极差、锁竞争严重,并发场景几乎不用。

五、各隔离级别优劣与适用场景

隔离级别 脏读 不可重复读 幻读 适用场景
READ_UNCOMMITTED 有 有 有 无生产用途
READ_COMMITTED 无 有 有 高并发、普通业务、查询多
REPEATABLE_READ 无 无 弱解决 支付、订单、账务(MySQL默认)
SERIALIZABLE 无 无 无 极低并发、强一致性场景

六、补充:Spring 事务高频失效场景

因为事务基于 AOP,所以以下场景事务完全不生效:

  • 方法不是 public

  • 同类内部 this 调用

  • try-catch 吞掉异常未抛出

  • 默认只回滚 RuntimeException,普通 Exception 不回滚

  • 传播机制配置错误导致事务挂起

七、全文总结

1. 事务原理:Spring 事务基于 AOP 动态代理,环绕拦截方法,自动开启、提交、回滚事务。

2. 两种方式:编程式灵活但侵入高;声明式注解优雅、统一规范、企业主流。

3. 传播机制:核心解决事务嵌套问题,默认 REQUIRED;REQUIRES_NEW 独立事务;NESTED 嵌套保存点。

4. 隔离级别:解决并发事务三大问题;MySQL 默认 RR 可重复读,平衡一致性与性能。

5. 取舍思想:高并发选 RC,金融一致性选 RR,绝对一致极低并发选串行化。

相关推荐
这个DBA有点耶3 天前
MVCC深入:Read View、版本链与快照读——InnoDB并发控制的内核
数据库·mysql·架构
DBA_G3 天前
从地面到云霄:GBase数据库在民航三大场景的落地实践
数据库
自由能燃气设备3 天前
商用全预混低氮冷凝锅炉免费方案vs付费方案对比+选型避坑指南
大数据·数据库·人工智能
科创致远3 天前
科创致远 ESOP 系统核心效能与实战价值展示
大数据·数据库·人工智能·精益工程
Bingo_BIG3 天前
Java Spring框架:单表的查询、新增、修改、删除、导入、导出
java·spring·前后端
2601_962218613 天前
万象生鲜系统称重自动多退少补算法解决生鲜非标品痛点
大数据·数据库·人工智能·python·算法
张洛闻Eren3 天前
k8s云原生【第十课】:水平 Pod 自动扩缩容
运维·数据库·云原生·kubernetes·github
于平安3 天前
MySQL-触发器
数据库·mysql
白远山3 天前
上海24小时自助健身房解决方案实战指南与经验分享
java·数据库·架构·需求分析
Omics Pro3 天前
斯坦福Nature+Science|广义虚拟细胞基础大模型
数据库·人工智能·算法·机器学习·自然语言处理