@Transactional 是 Spring AOP 代理,帮助自动管理数据库事务
必须 public、
必须由 Spring 代理调用(不能本类内部调用)
异常必须抛出去,不能被 try-catch 吞掉
类必须被 Spring 管理(@Service/@Component)
实际开发统一配 rollbackFor = Exception.class
传播机制默认 REQUIRED 足够,日志类用 REQUIRES_NEW
一、基本用法
- 加在哪里?
优先加在 业务层方法 / 类上
不要加在 Controller、Mapper 上
@Service
public class OrderService {
@Transactional
public void createOrder() {
// 多个 DB 操作
orderMapper.insert(...);
stockMapper.updateStock(...);
}
}
- 作用
自动开启事务
正常执行 → commit
抛异常 → rollback
同一线程内复用同一个数据库连接
二、核心常用属性
- rollbackFor:哪些异常回滚(非常重要)
默认行为:
只对 RuntimeException 和 Error 回滚
受检异常(Exception)不回滚
所以实际开发几乎都要写:
@Transactional(rollbackFor = Exception.class)
表示任何异常都回滚。
- noRollbackFor:哪些异常不回滚
@Transactional(rollbackFor = Exception.class,
noRollbackFor = BusinessWarnException.class)
- propagation:事务传播行为
默认:Propagation.REQUIRED
常用 3 个
REQUIRED
有事务就加入,没有就新建
业务 99% 用这个
REQUIRES_NEW
挂起当前事务,新建一个独立事务
适用场景:日志、消息发送、失败不影响主流程
NESTED
嵌套事务,基于数据库 savepoint
内层回滚只回滚到保存点,不影响外层 - isolation:事务隔离级别
默认:使用数据库默认隔离级别
可选:
Isolation.DEFAULT
Isolation.READ_UNCOMMITTED
Isolation.READ_COMMITTED
Isolation.REPEATABLE_READ
Isolation.SERIALIZABLE
Oracle 默认:READ_COMMITTED
MySQL InnoDB 默认:REPEATABLE_READ
- timeout:事务超时(秒)
@Transactional(timeout = 10)
事务执行超过 10 秒回滚。
- readOnly:只读事务
@Transactional(readOnly = true)
优化:不加锁、不记录 undo/redo
只查询时建议开启,性能更好
三、事务传播机制举例
- REQUIRED(默认)
A 有事务 → B 加入 A 事务
A 回滚 → B 一起回滚 - REQUIRES_NEW
A 调用 B
B 新建独立事务
B 异常回滚,A 可以捕获不回滚
A 回滚,不影响 B 已经提交的内容
适用:记录操作日志、发送消息。 - NESTED
B 是 A 的嵌套事务
B 回滚 → 只回滚 B,A 可继续
A 回滚 → B 一起回滚