Spring 事务核心知识 总结,覆盖原理、机制、常考点、易踩坑
一、什么是 Spring 事务(本质)
Spring 事务是 对数据库事务的统一抽象与管理机制,核心目标:
保证一组数据库操作要么全部成功,要么全部失败(ACID)
Spring 并不直接实现事务,而是 基于底层事务实现(JDBC / JTA)进行封装。
核心抽象接口:
Spring Framework 的 PlatformTransactionManager
二、Spring 事务的两种使用方式(必考)
1. 编程式事务(了解即可)
java
TransactionStatus status = transactionManager.getTransaction(definition);
try {
// 业务逻辑
transactionManager.commit(status);
} catch (Exception e) {
transactionManager.rollback(status);
}
特点:
- 灵活
- 侵入性强
- 实际项目很少用
2. 声明式事务(重点 + 面试主流)
java
@Transactional
public void createOrder() {
// 业务代码
}
本质:
-
AOP + 代理
-
在方法前后自动:
- 开启事务
- 提交 / 回滚事务
常用注解:
- @Transactional
三、Spring 事务的底层原理(高频面试)
核心链路(一定要能说清)
@Transactional
↓
Spring AOP(代理对象)
↓
TransactionInterceptor
↓
PlatformTransactionManager
↓
JDBC / JPA / MyBatis
关键点
- 通过 AOP 在方法调用前后增强
- 事务对象绑定到 当前线程(ThreadLocal)
- 同一线程中共享同一个数据库连接
面试回答模板:
Spring 事务是基于 AOP 实现的,
@Transactional会生成代理对象,在方法执行前通过PlatformTransactionManager开启事务,方法正常结束提交事务,出现异常时根据回滚规则进行回滚。
四、事务四大特性(ACID)------基础必答
| 特性 | 含义 |
|---|---|
| 原子性(Atomicity) | 操作要么全成功要么全失败 |
| 一致性(Consistency) | 事务前后数据状态合法 |
| 隔离性(Isolation) | 并发事务互不干扰 |
| 持久性(Durability) | 提交后数据永久保存 |
五、事务传播行为(Propagation)
面试最容易被追问的一块
常见传播行为(记住这 5 个)
| 行为 | 含义 | 使用场景 |
|---|---|---|
| REQUIRED(默认) | 有事务就加入,没有就新建 | 90% 场景 |
| REQUIRES_NEW | 总是新建事务 | 日志、审计 |
| SUPPORTS | 有就用,没有不用 | 查询 |
| NOT_SUPPORTED | 挂起当前事务 | 非事务逻辑 |
| NESTED | 嵌套事务(保存点) | 局部回滚 |
高频追问:
- REQUIRED vs REQUIRES_NEW 区别
- 内层异常是否影响外层事务
六、事务隔离级别(并发必考)
Spring 直接使用数据库隔离级别:
| 隔离级别 | 解决问题 |
|---|---|
| READ_UNCOMMITTED | 可能脏读 |
| READ_COMMITTED(Oracle 默认) | 防止脏读 |
| REPEATABLE_READ(MySQL 默认) | 防止不可重复读 |
| SERIALIZABLE | 串行,性能最低 |
面试重点:
- MySQL 默认隔离级别?
- 幻读如何解决?
七、回滚规则(非常容易踩坑)
1. 默认回滚规则(必背)
只回滚 RuntimeException 和 Error
❌ 不会回滚:
java
throw new Exception();
2. 指定回滚规则
java
@Transactional(rollbackFor = Exception.class)
面试追问:
为什么 Spring 默认不回滚 checked exception?
标准回答:
因为 checked exception 通常代表可预期的业务异常,而不是系统错误。
八、Spring 事务失效的 8 大原因(面试杀手锏)
常见失效场景
- 方法不是 public
java
@Transactional
private void test() {}
- 同类方法内部调用
java
this.methodA(); //不走代理
- 异常被 try-catch 吃掉
java
try {
...
} catch (Exception e) {
// 没抛出
}
- 抛出 checked exception
java
throw new Exception(); // 默认不回滚
-
数据库引擎不支持事务(MyISAM)
-
没有被 Spring 管理(new 出来的对象)
-
@Transactional 加在接口方法上(JDK 代理问题)
-
传播行为设置不当(REQUIRES_NEW)
面试建议:
至少能说出 3--5 个事务失效原因
九、@Transactional 的常用属性(面试可加分)
java
@Transactional(
propagation = Propagation.REQUIRED,
isolation = Isolation.READ_COMMITTED,
rollbackFor = Exception.class,
timeout = 30,
readOnly = true
)
十、一句话面试总结(背下来)
Spring 事务本质是基于 AOP 的声明式事务管理,通过
PlatformTransactionManager统一控制事务的开启、提交和回滚,事务基于线程绑定数据库连接,常见问题集中在传播行为、回滚规则以及代理失效场景。