干货!Spring里面@Transactional失效场景

简介: 【场景】明明使用Spring的AOP托管所有事务,在每个Service的函数中也加上了@Transactional注解,可依然还是出现数据不一致,事务不符合预期的情况呢?代码没报错,运行日志也无异常,怎么办呢?

【场景】

明明使用Spring的AOP托管所有事务,在每个Service的函数中也加上了@Transactional注解,可依然还是出现数据不一致,事务不符合预期的情况呢?代码没报错,运行日志也无异常,怎么办呢?

【答案】

也许不是你的语法没掌握好,不是注解没选对,而只是你使用的姿势不太对!没错,就是使用姿势不对。毕竟Aop这玩意都是动态代理干的活,动态代理不懂的,欢迎咨询度娘或者谷歌。动态代理带来的坏处就是,IDE(不论eclipse或idea)对动态运行的程序无法进行静态差错,因此只会进行常规的语法检查(这也不能怪IDE,毕竟AOP不是它擅长的)。


Spring 事务运行机制如下图所示:

image.png

【坑点】

坑一:@Transactional放在非public方法上。

原因:AbstractFallbackTransactionAttributeSource类调用computeTransactionAttribute()时,过滤了非public方法上事务配置信息(相当于没有配置无事务运行机制)。

image.png

所以:对于protected和private上定义的事务注解,spring Aop会自动无视的,这是最容易忽略的点。

坑二:不注意事务上下文环境

原因:错误配置事务。

image.png

所以:如果存在调用链的,请务必注意所有方式是否应该在一个事务环境中,如非必要,不要修改默认的传播特性。

坑三:未正确设置rollbackfor

原因:spring默认会对Error和RuntimeException进行事务回滚,但是其他异常则不会处理。放一个图你就知道了

image.png

所以:对于一些明确回滚的异常,直接在rollbackfor里面指定好。

image.png

坑四:try...catch...滥用


原因:spring Aop回滚的机制是捕获了应用程序抛出的指定异常,如果你try...catch...了,那Spring 会错误的认为当前运行正常,事务应该Commit。所以,此时的try...catch...就是画蛇添足了。


所以:尽量不要在业务方法中使用try...catch来捕获你的异常,防止影响了事务。


坑五:跨了线程的事务


      原因:如果事务方法内,开启了新线程去执行其他事务方法也是不受当前事务方法控制的。因为不同线程拥有的threadlocal 不一样。


所以:当你需要明确开启新线程,请分开处理。


坑六:数据库不支持


原因:这种情况出现的概率并不高,事务能否生效数据库引擎是否支持事务是关键。常用的MySQL数据库默认使用支持事务的innodb引擎。一旦数据库引擎切换成不支持事务的myisam,那事务就从根本上失效了。


以上6种方式,是日常开发当中比较容易出现的坑,请避免出现。还有其它的坑点,欢迎留言补充,谢谢。

目录
相关文章
|
5月前
|
缓存 Java 应用服务中间件
Spring Boot配置优化:Tomcat+数据库+缓存+日志,全场景教程
本文详解Spring Boot十大核心配置优化技巧,涵盖Tomcat连接池、数据库连接池、Jackson时区、日志管理、缓存策略、异步线程池等关键配置,结合代码示例与通俗解释,助你轻松掌握高并发场景下的性能调优方法,适用于实际项目落地。
945 5
|
11月前
|
Java Spring
Spring中事务失效的场景
因为Spring事务是基于代理来实现的,所以某个加了@Transactional的⽅法只有是被代理对象调⽤时, 那么这个注解才会⽣效 , 如果使用的是被代理对象调用, 那么@Transactional会失效 同时如果某个⽅法是private的,那么@Transactional也会失效,因为底层cglib是基于⽗⼦类来实现 的,⼦类是不能重载⽗类的private⽅法的,所以⽆法很好的利⽤代理,也会导致@Transactianal失效 如果在业务中对异常进行了捕获处理 , 出现异常后Spring框架无法感知到异常, @Transactional也会失效
|
9月前
|
人工智能 Java 数据库连接
Spring事务失效场景
本文深入探讨了Spring框架中事务管理可能失效的几种常见场景及解决方案,包括事务方法访问级别不当、方法内部自调用、错误的异常处理、事务管理器或数据源配置错误、数据库不支持事务以及不合理的事务传播行为或隔离级别。通过合理配置和正确使用`@Transactional`注解,开发者可以有效避免这些问题,确保应用的数据一致性和完整性。
738 10
|
10月前
|
Java 关系型数据库 MySQL
深入解析 @Transactional——Spring 事务管理的核心
本文深入解析了 Spring Boot 中 `@Transactional` 的工作机制、常见陷阱及最佳实践。作为事务管理的核心注解,`@Transactional` 确保数据库操作的原子性,避免数据不一致问题。文章通过示例讲解了其基本用法、默认回滚规则(仅未捕获的运行时异常触发回滚)、因 `try-catch` 或方法访问修饰符不当导致失效的情况,以及数据库引擎对事务的支持要求。最后总结了使用 `@Transactional` 的五大最佳实践,帮助开发者规避常见问题,提升项目稳定性与可靠性。
1596 12
|
Java 关系型数据库 MySQL
Spring 事务失效场景总结
Spring 事务失效场景总结
182 4
|
Java 关系型数据库 数据库
京东面试:聊聊Spring事务?Spring事务的10种失效场景?加入型传播和嵌套型传播有什么区别?
45岁老架构师尼恩分享了Spring事务的核心知识点,包括事务的两种管理方式(编程式和声明式)、@Transactional注解的五大属性(transactionManager、propagation、isolation、timeout、readOnly、rollbackFor)、事务的七种传播行为、事务隔离级别及其与数据库隔离级别的关系,以及Spring事务的10种失效场景。尼恩还强调了面试中如何给出高质量答案,推荐阅读《尼恩Java面试宝典PDF》以提升面试表现。更多技术资料可在公众号【技术自由圈】获取。
|
JavaScript Java 关系型数据库
Spring事务失效的8种场景
本文总结了使用 @Transactional 注解时事务可能失效的几种情况,包括数据库引擎不支持事务、类未被 Spring 管理、方法非 public、自身调用、未配置事务管理器、设置为不支持事务、异常未抛出及异常类型不匹配等。针对这些情况,文章提供了相应的解决建议,帮助开发者排查和解决事务不生效的问题。
2280 1
|
Java API Spring
springboot学习七:Spring Boot2.x 拦截器基础入门&实战项目场景实现
这篇文章是关于Spring Boot 2.x中拦截器的入门教程和实战项目场景实现的详细指南。
364 0
springboot学习七:Spring Boot2.x 拦截器基础入门&实战项目场景实现
|
Java API Spring
springboot学习六:Spring Boot2.x 过滤器基础入门&实战项目场景实现
这篇文章是关于Spring Boot 2.x中过滤器的基础知识和实战项目应用的教程。
491 0
springboot学习六:Spring Boot2.x 过滤器基础入门&实战项目场景实现
|
Java 数据安全/隐私保护 Spring
揭秘Spring Boot自定义注解的魔法:三个实用场景让你的代码更加优雅高效
揭秘Spring Boot自定义注解的魔法:三个实用场景让你的代码更加优雅高效