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,绝对一致极低并发选串行化。

相关推荐
一只鹿鹿鹿1 小时前
SCM流程图参考(PPT文件)
大数据·数据库·web安全·系统安全·流程图
ClouGence1 小时前
CloudDM 支持达梦、KingbaseES、GoldenDB,国产数据库也能统一管起来
数据库·sql·开源
举个栗子。2 小时前
DBX:20MB 驾驭 90+ 种数据库的极简开源数据库管理器
数据库·开源
逃逸线LOF2 小时前
SpringMVC拦截器 & 异常处理机制
数据库·mysql
科技小登2 小时前
重大活动安全保障方案怎么选?重保服务、攻防演练、应急响应与安全意识培训实战与边界
数据库·人工智能·安全
番茄你个西红42 小时前
金仓KFS同步工具常见问题解决方法
数据库
CarIise2 小时前
JDBC数据库操作与SQL注入防范
数据库·sql
CCYe、3 小时前
新模型上线、旧模型下线:企业AI网关如何管住模型版本
java·网络·数据库·人工智能
疯狂打码的少年3 小时前
【数据库技术】SQL嵌套查询(IN/EXISTS/ANY/ALL)
数据库·笔记·sql