spring事务失效场景
2026/6/16 7:21:55 网站建设 项目流程

这个问题是 Spring 面试高频题,面试官通常希望你不仅知道场景,还知道为什么失效(AOP代理机制)


核心原因

Spring 事务本质上是:

@Transactional ↓ AOP代理 ↓ TransactionInterceptor ↓ 开启事务 ↓ 执行方法 ↓ 提交/回滚

如果没有经过 Spring 代理对象:

事务不会生效

1. 方法不是 public

错误写法:

@Service public class UserService { @Transactional private void saveUser() { } }

失效原因:

Spring AOP 默认只代理:

public 方法

正确:

@Transactional public void saveUser() { }

2. 自调用(最经典)

@Service public class UserService { public void test() { saveUser(); } @Transactional public void saveUser() { } }

调用过程

this.saveUser()

而不是:

代理对象.saveUser()

绕过AOP。

事务失效。


面试官最爱问:

A(){ B(); } @Transactional B()

为什么事务不生效?

答案:

同类内部调用 没有经过代理对象

解决:

@Autowired private UserService userService; userService.saveUser();

或者:

AopContext.currentProxy()

3. final 方法

@Transactional public final void saveUser() { }

如果是 CGLIB:

原理:

生成子类 重写方法 增强事务

但是:

final

不能重写。

因此:

事务失效

4. static 方法

@Transactional public static void saveUser() { }

静态方法属于类:

Class

不属于对象。

代理无法拦截。

事务失效。


5. 捕获异常未抛出

错误:

@Transactional public void save() { try { int a = 1 / 0; } catch (Exception e) { } }

Spring判断:

方法正常结束

于是:

提交事务

不会回滚。


正确:

catch (Exception e){ throw e; }

或者:

TransactionAspectSupport .currentTransactionStatus() .setRollbackOnly();

6. 抛出检查异常

Spring默认:

RuntimeException Error

才回滚。


例如:

@Transactional public void save() throws Exception { throw new Exception(); }

默认:

不会回滚

解决:

@Transactional( rollbackFor = Exception.class )

7. 数据库引擎不支持事务

例如:

MyISAM

即使:

@Transactional

也没用。

因为:

数据库本身不支持事务

查看:

show table status;

应该:

InnoDB

8. 未被Spring管理

错误:

UserService service = new UserService();

此时:

自己new出来

不是IOC容器Bean。

没有代理。

事务失效。


正确:

@Autowired UserService service;

9. 多线程导致事务失效

@Transactional public void save() { executor.submit(() -> { userMapper.insert(); }); }

事务绑定:

ThreadLocal

主线程:

有事务

子线程:

没有事务

因此:

事务无法传递

10. 方法所在类没有被扫描

例如:

@Service

没加。

或者:

@ComponentScan

未扫描到。


Spring根本没创建Bean。

事务失效。


11. propagation 配置错误

例如:

@Transactional( propagation = NOT_SUPPORTED )

含义:

挂起当前事务

或者:

PROPAGATION_NEVER

要求:

不能存在事务

配置不当容易造成:

事务没有按预期生效

12. @Transactional加在接口上

public interface UserService { @Transactional void save(); }

JDK动态代理:

可能生效

CGLIB:

可能失效

最佳实践:

写实现类
@Service public class UserServiceImpl

总结

Spring事务底层基于AOP代理实现,本质是通过 TransactionInterceptor 在方法执行前开启事务、执行后提交事务、出现异常时回滚事务。因此凡是没有经过代理对象调用的场景都会导致事务失效。

常见失效场景包括:

  1. 方法不是 public;
  2. 同类内部自调用;
  3. final 方法;
  4. static 方法;
  5. 自己 new 对象而非 Spring Bean;
  6. 捕获异常未继续抛出;
  7. 抛出 Checked Exception 未配置 rollbackFor;
  8. 数据库不支持事务;
  9. 多线程导致事务无法通过 ThreadLocal 传播;
  10. Bean 未被 Spring 容器管理;
  11. propagation 配置不当。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询