一、Spring事务管理概述

在Java企业级开发中,Spring事务是保证数据一致性的核心机制。面试中,关于Spring事务的问题通常从基础概念出发,逐步深入到传播行为、隔离级别以及底层实现原理。Spring框架通过声明式事务管理,极大地简化了事务代码的开发,使得开发者只需关注业务逻辑,而无需处理繁琐的事务开启、提交和回滚操作。

Spring事务管理的核心接口是 PlatformTransactionManager,它定义了事务的基本操作。而 @Transactional 注解则是实现声明式事务的关键,它告诉Spring容器该方法需要事务支持。

二、Spring事务核心面试题解析

Q1: @Transactional 注解的工作原理是什么?

答案要点:

  1. ① Spring AOP:@Transactional 是基于AOP实现的。Spring容器在启动时会扫描带有该注解的Bean,并为其创建代理对象。
  2. ② 拦截器:当代理对象的方法被调用时,会经过 TransactionInterceptor 拦截器。
  3. ③ 事务管理:拦截器根据配置获取事务管理器(PlatformTransactionManager),开启事务,执行目标方法,最后根据执行结果提交或回滚事务。
// 示例代码
@Service
public class OrderService {
    @Transactional(rollbackFor = Exception.class)
    public void createOrder(Order order) {
        // 业务逻辑
        orderMapper.insert(order);
        // 如果发生异常,事务将回滚
    }
}

Q2: 请解释Spring事务的七大传播行为?

答案要点:

传播行为 描述 场景示例
REQUIRED 如果当前存在事务,则加入该事务;如果当前没有事务,则创建一个新事务。这是默认值。 大多数业务场景
REQUIRES_NEW 创建一个新事务,如果当前存在事务,则把当前事务挂起。 日志记录、独立操作
SUPPORTS 如果当前存在事务,则加入该事务;如果当前没有事务,则以非事务方式执行。 查询操作
NOT_SUPPORTED 以非事务方式执行操作,如果当前存在事务,则把当前事务挂起。 耗时且不需要事务的操作
MANDATORY 如果当前存在事务,则加入该事务;如果当前没有事务,则抛出异常。 强制要求事务环境
NEVER 以非事务方式执行,如果当前存在事务,则抛出异常。 绝对不能在事务中执行
NESTED 如果当前存在事务,则在嵌套事务内执行;如果当前没有事务,则创建一个新事务。 部分回滚场景

Q3: Spring事务的隔离级别有哪些?如何解决并发问题?

答案要点:

  • ① READ_UNCOMMITTED:读未提交。允许读取未提交的数据,可能导致脏读、不可重复读、幻读。
  • ② READ_COMMITTED:读已提交。防止脏读,但可能导致不可重复读和幻读。Oracle默认级别。
  • ③ REPEATABLE_READ:可重复读。防止脏读和不可重复读,但可能导致幻读。MySQL默认级别。
  • ④ SERIALIZABLE:串行化。最高级别,防止所有并发问题,但性能最低。

Spring默认的事务隔离级别是 DEFAULT,即使用数据库的默认隔离级别。

Q4: Spring事务失效的常见场景有哪些?

答案要点:

1. 方法非public

@Transactional 只能用于 public 方法上,否则事务不会生效。

2. 自调用问题

在同一个类中,A方法调用B方法,B方法的 @Transactional 不会生效。因为AOP代理的是Bean本身,自调用绕过代理对象。

3. 异常被捕获

如果方法内部 try-catch 捕获了异常,且未抛出,事务不会回滚。应使用 rollbackFor 指定回滚异常类型。

4. 数据库引擎不支持

只有 InnoDB 等支持事务的引擎才有效,MyISAM 不支持事务。

三、Spring事务源码深度解析

理解Spring事务的源码有助于解决复杂问题。核心流程如下:

  1. ① 代理创建:在Spring容器初始化时,AnnotationTransactionAttributeSource 解析 @Transactional 注解,生成事务属性。
  2. ② 拦截执行:TransactionInterceptor 拦截方法调用,获取事务属性,调用 TransactionManager。
  3. ③ 事务开启:AbstractPlatformTransactionManager 根据传播行为决定是开启新事务还是加入现有事务。
  4. ④ 资源绑定:通过 TransactionSynchronizationManager 将Connection与当前线程绑定,确保同一事务中使用的Connection是同一个。
  5. ⑤ 提交/回滚:方法执行完毕后,根据异常情况和rollbackFor配置,决定提交或回滚事务。

四、总结与建议

掌握Spring事务是Java后端开发的必备技能。面试中,建议从基础注解入手,逐步深入到传播机制和隔离级别,最后结合源码理解其实现原理。同时,要特别注意事务失效的场景,这是实战中最容易遇到的问题。

对于高级开发者,还需要了解分布式事务、动态数据源等高级主题,以应对更复杂的业务场景。