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

相关推荐
软件技术NINI11 小时前
基于SpringBoot和Vue的项目评审系统
javascript·vue.js·spring boot·后端·spring·毕业设计·毕设
skywalk816311 小时前
不用 SSH、不装数据库:我用 1 个 Python 脚本 + Git,把 15 个 AI Agent 串成了一条流水线
数据库·人工智能·python·ssh·集群
Decay__11 小时前
19_MySQL 告警与自动化运维 —— 告警分级收敛 / Webhook / 定时巡检 / 脚本库
运维·数据库·sql·mysql·架构
代码不停11 小时前
Spring Aop
java·数据库·spring
keyipatience11 小时前
MySQL 学习(4)常用数据类型
数据库·mysql
达梦产品与服务11 小时前
SQLark V4.2 更新 | 新增TiDB、SSL安全连接、数据字典、清空/截断表等40+项功能已上线!
数据库·安全·tidb·ssl
码农阿豪12 小时前
SQL Server数据迁移完成后,凌晨的数据库告警该怎么查?
数据库·sqlserver
bjzhang7512 小时前
sqlsugar入门
数据库·sqlsugar
全栈陈序员14 小时前
【Git】从入门到精通(十)—— 撤销与恢复:git checkout与git restore
运维·网络·数据库·git
ss27321 小时前
为什么PostgreSQL适合AI场景?
数据库·人工智能·postgresql