一、事务基础核心概念
1.1 什么是事务?
事务是一组数据库操作的最小执行单元 ,这组操作要么全部成功提交 ,要么全部失败回滚,保证数据的一致性。
1.2 事务的 ACID 四大特性(面试必考)
- 原子性(Atomicity):事务不可分割,要么全执行,要么全不执行
- 一致性(Consistency):事务执行前后,数据的完整性约束不变
- 隔离性(Isolation):并发事务之间互不干扰
- 持久性(Durability):事务提交后,数据永久生效,不会丢失
1.3 Spring 事务的定位
Spring 事务是对底层数据库事务的封装 ,提供声明式事务 (极简注解)和编程式事务(手动控制)两种实现,屏蔽了底层数据库连接的复杂性,让开发者专注业务逻辑。
二、Spring 事务核心实现原理
2.1 两种事务实现方式

2.2 Spring 事务底层核心原理
- 基于 AOP 动态代理实现 Spring 事务本质是 AOP 环绕通知 :
- 目标方法执行前:开启事务
- 目标方法正常执行:提交事务
- 目标方法抛异常:回滚事务
- 核心组件
PlatformTransactionManager:事务管理器(真正操作事务的核心接口)TransactionDefinition:事务定义(传播行为、隔离级别、超时时间等)TransactionStatus:事务运行状态
- 代理机制
- JDK 动态代理:代理接口
- CGLIB 代理:代理普通类
关键结论 :只有代理对象调用方法,才会触发事务!
三、Spring 事务传播行为
事务传播行为:多个事务方法相互调用时,事务如何传递 / 合并 / 新建 ,Spring 共定义7 种传播行为 ,由Propagation枚举定义。
3.1 7 种传播行为详解

3.2 核心传播行为重点区分
- REQUIRED vs REQUIRES_NEW
- REQUIRED:同一个事务,一起提交 / 回滚
- REQUIRES_NEW:独立事务,互不干扰
- NESTED vs REQUIRES_NEW
- NESTED:依赖父事务,父回滚子必回滚
- REQUIRES_NEW:完全独立,父子事务无关联
四、Spring 事务隔离级别
事务隔离级别是数据库层面 的规范,Spring 仅做封装,用于解决脏读、不可重复读、幻读三大并发问题。
4.1 三大并发问题
- 脏读 :一个事务读到另一个事务未提交的修改数据
- 不可重复读 :同一事务内,两次查询结果不一致(update导致)
- 幻读 :同一事务内,两次查询行数不一致(insert/delete导致)
4.2 4 种隔离级别(Spring 对应数据库标准)

4.3 Spring 配置方式
java
@Transactional(isolation = Isolation.REPEATABLE_READ)
五、Spring 事务异常处理(回滚规则,面试高频)
5.1 Spring 默认回滚规则
✅ 只回滚:运行时异常(RuntimeException)、错误(Error)
❌ 不回滚:编译时异常(Checked Exception,如 IOException、SQLException)
5.2 自定义回滚规则
通过rollbackFor/noRollbackFor指定回滚异常:
TypeScript
// 所有异常都回滚
@Transactional(rollbackFor = Exception.class)
// 指定异常不回滚
@Transactional(noRollbackFor = BusinessException.class)
5.3 事务不回滚的核心原因
- 抛出Checked 异常 且未配置
rollbackFor - 异常被try-catch 捕获,未抛出
- 非代理对象调用(内部方法调用)
- 方法不是 public 修饰
六、Spring 事务常用注解与使用方法
6.1 @Transactional核心属性全解
TypeScript
@Transactional(
propagation = Propagation.REQUIRED, // 传播行为
isolation = Isolation.REPEATABLE_READ, // 隔离级别
timeout = 30, // 超时时间(秒)
readOnly = false, // 是否只读事务
rollbackFor = Exception.class, // 回滚异常
noRollbackFor = RuntimeException.class // 不回滚异常
)
6.2 @Transactional使用规范
- 只能作用于 public 方法(private/static/final 方法事务失效)
- 类 / 接口级别:当前类所有 public 方法生效
- 方法级别:优先级高于类级别
- 不能作用于静态方法、私有方法
6.3 编程式事务(精准控制)
TypeScript
@Autowired
private TransactionTemplate transactionTemplate;
public void testTransaction() {
transactionTemplate.execute(status -> {
// 业务逻辑
userMapper.insert(user);
return true;
});
}
七、Spring 事务常见使用场景
7.1 单数据源常规事务(最常用)
TypeScript
@Service
public class OrderService {
@Autowired
private OrderMapper orderMapper;
@Autowired
private StockMapper stockMapper;
// 下单+扣库存,原子操作
@Transactional(rollbackFor = Exception.class)
public void createOrder(Order order) {
orderMapper.insert(order);
stockMapper.deductStock(order.getGoodsId());
}
}
7.2 嵌套事务场景
TypeScript
@Transactional
public void parent() {
// 主业务
child();
}
@Transactional(propagation = Propagation.REQUIRES_NEW)
public void child() {
// 子业务独立事务
}
7.3 只读事务(查询优化)
TypeScript
@Transactional(readOnly = true)
public List<User> getUserList() {
return userMapper.selectList();
}
只读事务作用:数据库优化、防止误写、提升查询性能
八、Spring 事务经典问题 + 解决方案
8.1 @Transactional事务失效场景

内部调用失效解决方案(最常用)
TypeScript
@Service
public class TestService {
// 注入自身代理对象
@Autowired
private TestService testService;
public void methodA() {
// 错误:this.methodB() 事务失效
// 正确:代理对象调用
testService.methodB();
}
@Transactional
public void methodB() {
// 业务逻辑
}
}
8.2 事务不回滚解决方案
- 检查异常是否为RuntimeException/Error
- 检查是否try-catch 吞了异常
- 检查是否配置
rollbackFor = Exception.class - 检查是否代理对象调用
8.3 嵌套事务数据不一致
使用REQUIRES_NEW保证子事务独立,避免父事务回滚影响子事务。
九、Spring 事务高频面试题
- Spring 事务的传播行为有哪些?默认是什么?
@Transactional注解失效的场景有哪些?- Spring 事务默认回滚什么异常?为什么不回滚 Checked 异常?
- Spring 事务的隔离级别有哪些?解决什么问题?
- REQUIRED 和 REQUIRES_NEW 的区别?
- Spring 事务的底层实现原理?
- 什么是声明式事务和编程式事务?区别是什么?
- 只读事务的作用是什么?
- 事务挂起是什么意思?
- NESTED 和 REQUIRES_NEW 的区别?
十、总结
- Spring 事务基于 AOP 动态代理实现,代理对象调用才生效
- 传播行为REQUIRED是默认值,满足 90% 业务场景
- 隔离级别REPEATABLE_READ(MySQL 默认)解决脏读、不可重复读
@Transactional只作用于 public 方法,异常被 catch 会导致不回滚- 开发核心避坑:避免内部调用、异常不要吞、指定 rollbackFor