Transactional注解详解
Transactional注解详解
目录
一、什么是 @Transaction(al) 注解
在 Spring Framework 中,@Transactional 是用于声明式事务管理的核心注解。
👉 本质作用:
让方法在执行时自动具备事务能力(开启事务 → 执行 → 提交 / 回滚)
一个直观例子
1 |
|
执行逻辑:
- 开启事务
- 执行
transfer() - 如果正常 → 提交事务 ✅
- 如果抛异常 → 回滚事务 ❌
二、作用范围
@Transactional 可以作用于:
- 方法:推荐将注解使用于方法上,不过需要注意的是:该注解只能应用到public方法上,否则不生效
- 类:作用于类上时,表示该类的所有 public 方法都具有事务功能
- 接口:不推荐,接口上的注解不会被实现类继承
三、底层原理(面试重点)
3.1 核心机制:AOP
@Transactional 是基于 Spring AOP 实现的。
👉 执行流程:
1 | 调用方法 → 进入代理对象 → 开启事务 → 调用目标方法 → 提交/回滚 → 返回 |
3.2 事务管理器(TransactionManager)
Spring 会根据配置选择不同实现:
| 类型 | 适用场景 |
|---|---|
DataSourceTransactionManager |
JDBC |
JpaTransactionManager |
JPA |
HibernateTransactionManager |
Hibernate |
👉 本质:
事务管理器 = 真正控制提交 / 回滚的人
3.3 为什么必须是 public 方法?
👉 因为 Spring AOP 默认使用 动态代理
- JDK 动态代理 → 只代理接口方法
- CGLIB → 代理类,但仍有限制
📌 结论:
非 public 方法不会被代理 → 事务失效
四、核心属性(高频面试)🔥
4.1 propagation(传播行为)
控制事务如何传播
| 值 | 含义 |
|---|---|
| REQUIRED(默认) | 有就用,没有就新建 |
| REQUIRES_NEW | 新开事务,挂起旧事务 |
| SUPPORTS | 有就用,没有就不用 |
| NOT_SUPPORTED | 强制非事务执行 |
| MANDATORY | 必须有事务 |
| NEVER | 必须没有事务 |
4.2 isolation(隔离级别)
对应数据库事务隔离级别:
| 级别 | 问题 |
|---|---|
| READ_UNCOMMITTED | 脏读 |
| READ_COMMITTED | 不可重复读 |
| REPEATABLE_READ | 幻读 |
| SERIALIZABLE | 最严格 |
4.3 rollbackFor(回滚规则)
默认:
1 | 只对 RuntimeException 回滚 |
👉 自定义:
1 |
4.4 timeout / readOnly
| 属性 | 作用 |
|---|---|
| timeout | 超时自动回滚 |
| readOnly | 只读优化(提高性能) |
五、常见坑(面试杀手)⚠️
❌ 1. 同类方法调用失效
1 | public void A() { |
👉 原因:
没走代理对象(this调用)
❌ 2. 捕获异常不抛出
1 |
|
👉 解决:
1 | throw e; |
❌ 3. 非 public 方法
1 |
|
❌ 4. 数据库不支持事务
比如:
- MyISAM ❌(不支持事务)
- InnoDB ✅
六、执行流程总结(必背)
1 | @Transactional 方法调用 |
七、面试总结(高频八股)
⭐ 核心一句话
@Transactional是 Spring 基于 AOP 实现的声明式事务管理,通过事务管理器控制事务的开启、提交和回滚。
⭐ 高频面试问题
@Transactional 为什么会失效?
- 方法不是 public
- 同类调用(未走代理)
- 异常被吞
- 数据库不支持事务
Spring 事务是如何实现的?
👉 回答模板:
Spring 通过 AOP 为目标方法创建代理,在方法执行前开启事务,执行后根据是否发生异常决定提交或回滚。
事务传播行为最常用的是哪个?
👉 REQUIRED(默认)
rollbackFor 为什么重要?
👉 因为默认只回滚 RuntimeException