每日八股day24

本系列帖子为鼠鼠复习八股巩固记忆和个人理解所写,如有错误纯属本人实力不佳,欢迎各位大佬阅读指正

1.Spring的事务什么情况下会失效?

底层原理:@Transaction事务依靠AOP动态代理实现,方法调用必须经过代理对象,增强逻辑(开启/提交/回滚事务)才能执行。

同类内部方法自调用

在同一个Service中,使用this.xxx()调用本类带有@Transactional的方法,this指向原生目标对象,绕过代理对象,事务通知无法执行,事务失效。

事务方法非public修饰

private、protected、默认访问权限的方法添加@Transactionl失效,CGLIB动态代理生成子类,无法重写非public方法,不能完成增强。(static,final修饰的方法同样无法被代理增强,事务失效)。

异常被try-catch捕获且未重新抛出

事务拦截器依靠捕获方法抛出的异常判断是否回滚,异常被捕获吃掉,没有向外抛出,代理感知不到异常,不会触发回滚,同时Spring事务默认只对RuntimeException、Error触发回滚,普通受检异常不回滚,需要动手配置。

事务传播行为配置不当

例如:Propagation.SUPPORTS外层不存在事务时,当前方法以非事务方式运行。

Propagation.NOT_SUPPORTED强制挂起已有事务,使用非事务执行,配置错误会表现出事务不生效。

数据库存储引擎不支持事务

如MySQL使用MyISAM引擎,本身不支持事务,无论注释如何配置都无效,需要更换为InnoDB。

跨线程执行数据库操作

Spring事务信息存放在ThreadLocal,事务上下文绑定当前线程。

新开子线程执行DB操作,子线程拥有独立连接,无法加入主线程事务,不能统一回滚。

@Transaction仅标注在接口方法上

使用JDK动态代理场景下存在识别风险,规范需要将注解加在实现类public方法上。

2.Spring的事务,使用this调用是否生效?

不生效,Spring的@Transaction声明事务底层依靠AOP动态代理实现,事务的创建、提交、回滚逻辑全部写在代理对象的增强逻辑中,在同一个类内部使用this方法调用带有@Transaction的方法,this代表原始目标对象,不是Spring生成的代理对象,方法调用不会经过AOP拦截器,事务增强逻辑不会执行,事务失效。

追问:this 内部调用事务失效,有哪些解决方案?

this指向原生对象,不走AOP代理,事务增强逻辑无法执行。

三种解决方案:

自行注入,使用self.方法调用,self是容器中的代理对象

将带有事务的方法抽取到另外一个Service,跨类调用

通过AopContext.currentProxy()获取代理对象,必须额外开启配置。

相关推荐
露天赏雪9 小时前
第3篇:Sentinel熔断降级实战:大模型接口抖动时的服务兜底方案
java·开发语言·人工智能·spring boot·spring·servlet·sentinel
captain37610 小时前
▲统一功能——DispatcherServlet源码分析
java·spring·java-ee·log4j·maven
TeamDev19 小时前
使用 JxBrowser 在桌面应用中集成 Spring
java·前端·后端·spring·混合应用·jxbrowser·浏览器控件
SL_staff1 天前
从配置失效到逻辑复用:JVS-Logic 如何构建可治理的业务编排中枢
java·spring·产品
程序员吕洞宾2 天前
开源多维表格SmartTable v1.6.10 —— 用户名登录、数据评论及@人、表单分享二维码、性能优化、部署及升级优化
spring·性能优化·开源
liangbo72 天前
Spring系列03:Bean 的三种注册方式
java·spring
CoderYanger2 天前
Java EE 进阶:8.MyBatis 操作数据库(入门)(第一弹)
java·数据库·spring·面试·职场和发展·java-ee·mybatis
哦虎!2 天前
【JavaEE进阶】SpringIoC&DI
spring
敲代码的小小酥2 天前
谈SpringMVC与Spring WebFlux的区别与适用场景
java·后端·spring
风若飞2 天前
Spring Ai 入门遇到问题1
java·后端·spring