同一个类中,事务方法调用非事务方法时,事务是可以生效的。反例事务不生效见以下 4. 同一个类中,方法内部调用
@Autowired private XXXMapper xxxMapper;
@Autowired
private YYYMapper yyyMapper;
@Transactional
public ResultVO<AssetChangeVO> changeAssetDetail{
xxxMapper.execute();
}
private void copyYYY()
{
yyyMapper.copy("xxx","yyy");
}
-
前言
-
1. 你的service类没有被Spring管理
-
2.没有在Spring配置文件中启用事务管理器
-
3. 事务方法被final、static关键字修饰
-
4. 同一个类中,方法内部调用
-
5.方法的访问权限不是public
-
6. 数据库的存储引擎不支持事务
-
7 .配置错误的 @Transactional 注解
-
8.事务超时时间设置过短
-
9. 使用了错误的事务传播机制
-
10. rollbackFor属性配置错误
-
11.事务注解被覆盖导致事务失效
-
12.嵌套事务的坑
-
13. 事务多线程调用
-
14.异常被捕获并处理了,没有重新抛出
-
15. 手动抛了别的异常

前言
日常开发中,我们经常使用到spring事务。最近一位朋友去美团面试,被问了这么一道面试题: Spring 事务在哪几种情况下会不生效? 今天田螺哥跟大家聊聊,spring事务不生效 的15种场景。

1. 你的service类没有被Spring管理
//@Service (注释了@Service)
public class TianLuoServiceImpl implements TianLuoService {
@Autowired
private TianLuoMapper tianLuoMapper;
@Autowired
private TianLuoFlowMapper tianLuoFlowMapper;
@Transactional
public void addTianLuo(TianLuo tianluo) {
//保存tianluo实体数据库记录
tianLuoMapper.save(tianluo);
//保存tianluo流水数据库记录
tianLuoFlowMapper.saveFlow(buildFlowByTianLuo(tianluo));
}
}
-
事务不生效的原因 :上面例子中,
@Service注解注释之后,spring事务(@Transactional)没有生效,因为Spring事务是由AOP机制实现的,也就是说从Spring IOC容器获取bean时,Spring会为目标类创建代理,来支持事务的。但是@Service被注释后,你的service类都不是spring管理的,那怎么创建代理类来支持事务呢 。 -
解决方案 :加上
@Service注解。
2.没有在Spring配置文件中启用事务管理器
@Configuration
public class AppConfig {
// 没有配置事务管理器
}
@Service
public class MyService {
@Transactional
public void doSomething() {
// ...
}
}
-
事务不生效的原因 :没有在
AppConfig中配置事务管理器,因此Spring无法创建事务代理对象,导致事务不生效。即使在MyService中添加了@Transactional注解,该方法也不会被Spring管理的事务代理拦截。 -
解决方案 :为了解决这个问题,应该在
AppConfig中配置一个事务管器。例如:
@Configuration
public class AppConfig {
@Bean
public PlatformTransactionManager transactionManager() {
return new DataSourceTransactionManager(dataSource());
}
}
@Service
public class MyService {
@Transactional
public void doSomething() {
// ...
}
}
如果是
Spring Boot项目,它默认会自动配置事务管理器并开启事务支持。
3. 事务方法被final、static关键字修饰
@Service
public class TianLuoServiceImpl {
@Autowired
private TianLuoMapper tianLuoMapper;
@Autowired
private TianLuoFlowMapper tianLuoFlowMapper;
@Transactional
public final void addTianLuo(TianLuo tianluo) {
//保存tianluo实体数据库记录
tianLuoMapper.save(tianluo);
//保存tianluo流水数据库记录
tianLuoFlowMapper.saveFlow(buildFlowByTianLuo(tianluo));
}
}
-
事务不生效的原因 :如果一个方法被声明为
final或者static,则该方法不能被子类重写,也就是说无法在该方法上进行动态代理,这会导致


1262

被折叠的 条评论
为什么被折叠?



