每日八股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()获取代理对象,必须额外开启配置。

相关推荐
Bingo_BIG5 天前
Java Spring框架:单表的查询、新增、修改、删除、导入、导出
java·spring·前后端
paopaokaka_luck5 天前
智慧社区综合服务小程序(人脸识别、AI问答、Echarts图形化分析)
前端·javascript·spring boot·spring·数据分析·echarts
牧瀬クリスだ5 天前
YAML配置详解:SpringBoot实战指南
java·spring·yml
需要8265 天前
JVM 内存区域与对象创建:一次 GC 从哪来
java·jvm·spring boot·spring·servlet·tomcat
paopaokaka_luck5 天前
考研政治刷题小程序(AI推荐题目、ECharts数据分析、章节练习与专项训练、模拟考试、错题本与收藏夹、学习打卡与目标管理、题库和组卷维护)
前端·javascript·spring boot·spring·数据分析·echarts
步行cgn5 天前
Spring 基于 XML 的自动装配:byType 详解
java·后端·spring
边境悍匪5 天前
蜗牛学苑 Java 智能体学习 Day46|贯穿项目 2 思维导图复盘
java·开发语言·vue.js·学习·spring
步行cgn6 天前
Spring c 命名空间注入详解
java·后端·spring
需要8266 天前
MySQL 索引 B+ 树与“查询为什么变慢了
java·spring boot·spring·spring cloud·tomcat
vx-程序开发6 天前
【计算机毕设】django校园跑腿服务系统83141
java·数据库·vue.js·spring boot·spring·elasticsearch·django