---
title: Spring 事务核心：三层结构与失效清单
type: concept
domain: spring
tags: [spring, transaction, transactional, transactionmanager, propagation]
status: learning
created: 2026-09-28
last_reviewed: 2026-09-28
method: feynman
related_questions:
  - "Spring 中 @Transactional 事务的实现原理"
  - "Spring 事务失效可能是哪些原因？"
related_knowledge:
  - ./spring-ioc-core.md
  - ./spring-aop-core.md
visualizations: []
anki_cards: 8
interview_rounds:
  - "2026-09-28-round-1"
---

# Spring 事务核心：三层结构与失效清单

> Spring 事务的三层架构、7 种传播机制、10 条失效清单与规避方案

## TL;DR（3-5 句话，面试前 30 秒扫完）

- **事务三层结构**：@Transactional 注解 + TransactionInterceptor + PlatformTransactionManager
- **两大前提**：数据库支持事务 + 当前对象是 AOP 代理对象
- **7 种传播机制**：REQUIRED / REQUIRES_NEW / SUPPORTS / NOT_SUPPORTED / MANDATORY / NESTED / NEVER
- **10 条失效清单**：注册 Bean / new / 自调用 / 方法可见性 / 非 public / catch 吞异常 / 传播机制 / 数据库引擎 / @Enable / 注解位置

## 关键结论

- **结论 A（三层结构）**：@Transactional 注解 → TransactionInterceptor → PlatformTransactionManager
- **结论 B（两大前提）**：数据库支持事务 + 当前对象是 AOP 代理对象
- **结论 C（异常回滚）**：默认只对 RuntimeException 回滚，可通过 rollbackFor/noRollbackFor 自定义
- **结论 D（10 条失效清单）**：注册 Bean / new / 自调用 / 方法可见性 / 非 public / catch 吞异常 / 传播机制 / 数据库引擎 / @Enable / 注解位置

## 完整讲解（费曼四步）

### STEP 1 · 概念（一句话定义）

- **Spring 事务**：基于 AOP 代理的声明式事务管理，通过 @Transactional 注解自动管理事务生命周期
- **PlatformTransactionManager**：Spring 事务管理的核心接口，负责事务的开启、提交、回滚
- **传播机制**：定义事务在方法调用链中的传播行为

### STEP 2 · 大白话（生活类比）

> **类比（Spring 事务）**：就像银行的"转账流程"——你发起转账（开启事务）→ 检查余额（事务内操作）→ 确认转账（提交事务）；如果检查余额时发现余额不足（异常），转账会取消（回滚事务）。

### STEP 3 · 底层（细节 + 代码/表格）

#### 3.1 事务三层结构

| 层级 | 组件 | 职责 |
|------|------|------|
| **注解层** | @Transactional | 声明事务边界和属性 |
| **拦截器层** | TransactionInterceptor | AOP 拦截器，管理事务生命周期 |
| **管理器层** | PlatformTransactionManager | 事务的核心接口，负责开启/提交/回滚 |

**典型实现类**：
- `DataSourceTransactionManager`：JDBC 事务管理器
- `JtaTransactionManager`：JTA 事务管理器
- `JpaTransactionManager`：JPA 事务管理器

#### 3.2 底层 JDBC 操作

```java
// 开启事务
Connection connection = dataSource.getConnection();
connection.setAutoCommit(false);

// 执行事务内操作
// ...

// 提交事务
connection.commit();

// 回滚事务
connection.rollback();
```

#### 3.3 7 种传播机制

| 传播机制 | 含义 | 典型场景 |
|---------|------|---------|
| **REQUIRED** | 有事务则加入，无事务则新建 | 默认值，大多数场景 |
| **REQUIRES_NEW** | 总是新建事务，挂起当前事务 | 日志记录、审计 |
| **SUPPORTS** | 有事务则加入，无事务则非事务执行 | 查询操作 |
| **NOT_SUPPORTED** | 总是非事务执行，挂起当前事务 | 不需要事务的查询 |
| **MANDATORY** | 必须在事务中，无事务则抛异常 | 必须在事务中的操作 |
| **NESTED** | 有事务则嵌套事务，无事务则新建 | 子事务回滚不影响父事务 |
| **NEVER** | 必须无事务，有事务则抛异常 | 不需要事务的操作 |

#### 3.4 异常回滚规则

**默认行为**：
- 只对 `RuntimeException` 和 `Error` 回滚
- 对受检异常（Checked Exception）不回滚

**自定义规则**：
```java
@Transactional(rollbackFor = Exception.class)  // 所有异常都回滚
@Transactional(noRollbackFor = BusinessException.class)  // 指定异常不回滚
```

**关键坑**：**异常被 catch 吞掉，事务不会回滚**
```java
@Transactional
public void methodA() {
    try {
        methodB();  // 抛异常
    } catch (Exception e) {
        // 吞掉异常，事务不会回滚！
        log.error("异常", e);
    }
}
```

#### 3.5 10 条失效清单

| # | 失效场景 | 原因 | 规避方案 |
|---|---------|------|---------|
| 1 | **Bean 未注册** | 目标类未被 @Component 标注 | 确保目标类被 Spring 管理 |
| 2 | **直接 new** | 不走 Spring 容器，没有代理 | 使用 @Autowired 注入 |
| 3 | **自调用** | 类内部方法调用不经过代理 | 注入自身代理（@Lazy / @Resource） |
| 4 | **方法 private/final/static** | CGLIB 无法继承 final 类，JDK 代理不处理非 public 方法 | 方法改为 public、非 final |
| 5 | **非 public 方法** | JDK 代理只处理 public 方法 | 方法改为 public |
| 6 | **异常被 catch 吞掉** | 事务拦截器无法感知异常 | 不要吞掉异常，或重新抛出 |
| 7 | **传播机制选错** | 如 REQUIRES_NEW 挂起当前事务 | 根据场景选择正确的传播机制 |
| 8 | **数据库引擎不支持** | 如 MySQL MyISAM 不支持事务 | 使用 InnoDB 引擎 |
| 9 | **@EnableTransactionManagement 未开启** | Spring 事务管理未启用 | 添加 @EnableTransactionManagement（SpringBoot 默认已开启） |
| 10 | **注解加在字段/构造器** | @Transactional 只能标注在方法或类上 | 确保注解位置正确 |

### STEP 4 · 简化（比喻/口诀）

> **事务三层口诀**：注解 + 拦截器 + 管理器（3 层结构记 3 个字）。

> **两大前提口诀**：数据库支持 + 代理对象（2 个前提记 2 个字）。

> **10 条失效口诀**：注册、new、自调用、可见性、public、catch、传播、引擎、Enable、位置（10 个字记 10 条）。

## 常见误区（从面试记录提炼）

- **误区 1**："事务回滚是捕获异常" → 正确说法：**异常回滚是注解声明**（rollbackFor/noRollbackFor），不是捕获
- **误区 2**："catch 异常不会影响事务" → 正确说法：**catch 吞掉异常，事务不会回滚**
- **误区 3**："事务失效只有 3 种原因" → 正确说法：**完整 10 条清单**（注册/new/自调用/可见性/public/catch/传播/引擎/Enable/位置）

## 延伸追问（面试追问预演）

1. **追问 A**：Spring 事务的三层结构是什么？
   - 要点：@Transactional 注解 → TransactionInterceptor → PlatformTransactionManager

2. **追问 B**：Spring 事务的两大前提是什么？
   - 要点：数据库支持事务 + 当前对象是 AOP 代理对象

3. **追问 C**：Spring 事务的 7 种传播机制是什么？
   - 要点：REQUIRED / REQUIRES_NEW / SUPPORTS / NOT_SUPPORTED / MANDATORY / NESTED / NEVER

4. **追问 D**：Spring 事务的 10 条失效清单是什么？
   - 要点：注册 Bean / new / 自调用 / 方法可见性 / 非 public / catch 吞异常 / 传播机制 / 数据库引擎 / @Enable / 注解位置

5. **追问 E**：为什么异常被 catch 吞掉事务不会回滚？
   - 要点：事务拦截器无法感知异常，需要异常向上抛出才能触发回滚

## 速查表（面试前 30 秒扫完）

```
事务三层 · 注解 + 拦截器 + 管理器（@Transactional → TransactionInterceptor → PlatformTransactionManager）
两大前提 · 数据库支持 + 代理对象
7 种传播 · REQUIRED/REQUIRES_NEW/SUPPORTS/NOT_SUPPORTED/MANDATORY/NESTED/NEVER
异常回滚 · 默认只对 RuntimeException 回滚 · rollbackFor/noRollbackFor 自定义 · catch 吞异常不回滚
10 条失效 · 注册/new/自调用/可见性/public/catch/传播/引擎/Enable/位置
常见错点：事务回滚是捕获异常 ❌ / catch 异常不影响事务 ❌ / 事务失效只有 3 种 ❌
```

## 关联题目（题库）

- [ ] 《Spring 中 @Transactional 事务的实现原理》—— 2026-09-28 Round 1, 评分 ⭐⭐⭐⭐
- [ ] 《Spring 事务失效可能是哪些原因？》—— 2026-09-28 Round 1, 评分 ⭐⭐⭐

## 关联知识

- [Spring IoC 核心](./spring-ioc-core.md)
- [Spring AOP 核心](./spring-aop-core.md)

## Anki 候选卡片

以下知识点适合做 Anki 卡片：

1. **正**：Spring 事务的三层结构是什么？**反**：@Transactional 注解 → TransactionInterceptor → PlatformTransactionManager
2. **正**：Spring 事务的两大前提是什么？**反**：数据库支持事务 + 当前对象是 AOP 代理对象
3. **正**：Spring 事务的 7 种传播机制是什么？**反**：REQUIRED / REQUIRES_NEW / SUPPORTS / NOT_SUPPORTED / MANDATORY / NESTED / NEVER
4. **正**：Spring 事务默认对哪些异常回滚？**反**：默认只对 RuntimeException 和 Error 回滚
5. **正**：如何自定义事务回滚规则？**反**：@Transactional(rollbackFor = Exception.class) / @Transactional(noRollbackFor = BusinessException.class)
6. **正**：为什么异常被 catch 吞掉事务不会回滚？**反**：事务拦截器无法感知异常，需要异常向上抛出才能触发回滚
7. **正**：Spring 事务的 10 条失效清单是什么？**反**：注册 Bean / new / 自调用 / 方法可见性 / 非 public / catch 吞异常 / 传播机制 / 数据库引擎 / @Enable / 注解位置
8. **正**：SpringBoot 默认是否开启事务管理？**反**：默认已开启（@EnableTransactionManagement 默认已启用）

---

*最后更新：2026-09-28*
