SpringBoot事务
# @Transactional
@Transactional 是 Spring 的事务管理注解,用来声明某个方法或类运行时需要事务支持。
注意事项
- 只能作用在 public 方法(Spring AOP 的限制)。
- 1、transactionManager:事务管理器; 控制事务的获取、提交、回滚。
- 底层默认使用哪个事务管理器?默认使用 JdbcTransactionManager;
- 原理:
TransactionManager负责事务的提交和回滚实现,使用切面技术对添加了@Transactional注解的所有类,控制何时提交和回滚。
- 1、事务管理器:TransactionManager; 控制提交和回滚的实现
- 2、事务拦截器:TransactionInterceptor: 通过@Transactional注解切面的方式控制何时提交和回滚
- completeTransactionAfterThrowing(txInfo, ex); 在这个时候回滚
- commitTransactionAfterReturning(txInfo); 在这个时候提交
# @Transactional核心属性
| 属性 | 作用 | 默认值 |
|---|---|---|
timeout | 事务超时时间(秒) | -1(不超时) |
readOnly | 是否只读事务(提高查询性能) | false |
rollbackFor | 指定遇到哪些异常回滚 | 运行时异常 |
noRollbackFor | 指定遇到哪些异常不回滚 | 空 |
isolation | 事务隔离级别(解决并发时数据一致性问题) | 数据库默认 |
propagation | 事务传播行为(方法调用时事务如何传播) | REQUIRED |
rollbackFor和noRollbackFor
异常:
- 运行时异常(unchecked exception【非受检异常】)
- 编译时异常(checked exception【受检异常】)
【回滚的默认机制】
- 运行时异常:回滚
- 编译时异常:不回滚
rollbackFor【可以指定哪些异常需要回滚】
- 【回滚 = 运行时异常(默认) + rollbackFor指定回滚异常】
noRollbackFor(同 noRollbackForClassName):指明哪些异常不需要回滚。
- 【不回滚 = 编译时异常(默认) + noRollbackFor指定不回滚异常】

# 隔离级别Isolation
隔离级别解决的是读取操作的设置。
读未提交(Read Uncommitted)
- 事务可以读取未被提交的数据,易产生脏读、不可重复读和幻读等问题
读已提交(Read Committed)Oracle默认设置
- 事务只能读取已经提交的数据,可避免脏读,但可能引发不可重复读和幻读。
可重复读(Repeatable Read)快照读 MySQL默认设置
- 同一事务期间多次重复读取的数据相同。避免脏读和不可重复读,但仍有幻读的问题
串行化(Serializable)
- 最高隔离级别,完全禁止了并发,只允许一个事务执行完毕之后才能执行另一个事务
| 级别 | 脏读 | 不可重复读 | 幻读 |
|---|---|---|---|
| 读未提交 | √ | √ | √ |
| 读已提交 | × | √ | √ |
| 可重复读 | × | × | √ |
| 串行化 | × | × | × |
- REPEATABLE_READ: 可重复读。 快照读。 MySQL默认
- READ_COMMITTED: 读已提交。 当前读。 Oracle默认
脏读是指一个事务(事务 A)读取了另一个事务(事务B)尚未提交的修改数据。如果后续事务 B 发生回滚(Rollback),那么事务 A 读取到的数据就是 “无效的”“脏的”(相当于不存在的虚假数据)。
不可重复读 在同一个事务内,多次读取同一行数据,在读取过程中,其他事务修改了该行数据并提交,导致多次读取的结果不一致。
幻读 幻读是指在同一个事务内,多次执行同一个查询,却返回了不同数量的结果集。就好像数据凭空出现或消失了一样,让人感觉产生了幻觉。
# 传播行为Propagation
定义:当一个事务(小事务)方法被另一个事务(大事务)方法调用时,小事务该以何种状态存在?事务属性该如何传播下去?
| 传播行为 | 说明 |
|---|---|
REQUIRED | 支持当前事务,当前有事务就加入,没有就新建一个(默认值) |
REQUIRES_NEW | 支持当前事务,总是新建事务,挂起原来的 |
SUPPORTS | 支持当前事务,有事务就加入,没有就不用事务 |
NOT_SUPPORTED | 非事务执行,不支持事务,如果存在当前事务则挂起原来的 |
NEVER | 非事务执行,不支持事务,如果存在当前事务则报错 |
MANDATORY | 支持当前事务,如果不存在则抛出异常 |
NESTED | 支持当前事务,如果当前存在事务,则在嵌套事务中执行,否则像 REQUIRED 一样运行 |
说明 当前事务指的的是父方法的事务
事务详解
A() {
B(){//REQUIRED
F();//REQUIRES_NEW
G();//REQUIRED
H();//REQUIRES_NEW
}
C(){//REQUIRES_NEW
I();//REQUIRES_NEW
J();//REQUIRED
}
D(){//REQUIRES_NEW
K();//REQUIRES_NEW
L();//REQUIRES_NEW
}
E(){//REQUIRED
M();//REQUIRED
N();//REQUIRES_NEW
}
}
如果方法A出现异常:则C(i,j),D(K,L),F,H,N 不回滚,其他B,G,E,M回滚
如果方法L出现异常:则K,B,F,H,C(i,j) 不回滚, E整个代码走不到,其他B,G回滚
如果方法M出现异常:则F,H,C(i,j),D(K,L) 不回滚, 其他E,M,B,G回滚
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
Last Updated: 2025/11/21, 16:34:23