首页 > 其他分享 >springboot中事务失效的一些场景以及如何应对

springboot中事务失效的一些场景以及如何应对

时间:2024-07-03 22:08:26浏览次数:24  
标签:insert 回滚 场景 springboot 对象 void 事务 失效 Transactional

@Transactional是基于AOP的,因此事务发生需要两个条件:

1.添加@Transactional注解

2.使用代理对象

 

失效场景:同一个类中直接调用的类方法,而被调方法带有@Transactional

下面这段代码会抛出runtimeException异常,但是事务不会回滚。即insert生效了

因为b()在调用a()方法时,对象已经不再是代理对象,而是普通对象。而aop都是基于代理对象实现的,即aop是不关心普通对象头顶上注解的,因此事务会失效

@Transactional
public void a(){
int insert = mapper.insert(Entity);
if(insert<=0)
throw new RuntimeException("插入信息失败!");

}
public void b(){
a();
}

如果我们将代码块修改为下面这样,那么他是可以正常回滚的。此时其实只是发生了b()的回滚,因为a()抛出了异常给b()。如果这样写,其实a()的注解是无效的。达不到预期缩减事务代码块的目的



@Transactional
public void a(){
int insert = mapper.insert(Entity);
if(insert<=0)
throw new RuntimeException("插入信息失败!");

}
@Transactional
public void b(){
a();
}


解决办法:

那么如何让a()方法事务能够回滚呢?触发的两个条件,我们已经具备了第一个添加@Transactional注解,但是目前是普通的对象,而非代理对象。因此我们需要让a()由代理对象来实现

下例中,我们将a()方法写入service接口,然后通过注册一个本方法的bean,实现了代理对象,满足上述条件,可以对a()单独实现回滚

@Autowired
Service service;
@Transactional
public void a(){
int insert = mapper.insert(Entity);
if(insert<=0)
throw new RuntimeException("插入信息失败!");

}
public void b(){
service.a();
}

 

除此以外,还有一些其他让事务不能回滚的原因:

1.a()方法是private或者final的

我们知道,aop的实现是基于代理对象的。上述解决办法中,如果我们没有区分出impl。

那么一旦a方法私有化或者不可变的,会导致代理对象作为普通对象的子类,没有权限去通过AOP重写方法,会导致爆出空指针异常

2.数据库不支持事务、没有bean化的类:神仙难救

3.如果没有捕获到runtime或者error,spring是不会触发回滚的。

关于这点阿里规范中要求在@Transactional中指定rollbackFor,合理使用一般不会出现这个问题

还有如果仅仅是捕获了异常而没有抛出,那么也是不会触发回滚的

标签:insert,回滚,场景,springboot,对象,void,事务,失效,Transactional
From: https://www.cnblogs.com/kun1790051360/p/18282645

相关文章

  • springboot实验报告管理系统-计算机毕业设计源码10596
    目录1绪论1.1选题背景与意义1.2国内外研究现状1.3论文结构与章节安排2系统分析2.1可行性分析2.2系统流程分析2.2.1系统开发流程2.2.2用户登录流程2.2.3系统操作流程2.2.4添加信息流程2.2.5修改信息流程2.2.6删除信息流程2.3 系统功能分......
  • springboot实验报告管理系统-计算机毕业设计源码10596
    目录1绪论1.1选题背景与意义1.2国内外研究现状1.3论文结构与章节安排2系统分析2.1可行性分析2.2系统流程分析2.2.1系统开发流程2.2.2用户登录流程2.2.3系统操作流程2.2.4添加信息流程2.2.5修改信息流程2.2.6删除信息流程2.3 系统功能分......
  • springboot线程池简单配置
    @ConfigurationpublicclassThirdPartyOilSmallTaskConfig{@Bean("thirdPartyOilSmallTaskExecutor")publicThreadPoolTaskExecutoruniteOilThreadPoolTaskExecutor(){ThreadPoolTaskExecutorexecutor=newThreadPoolTaskExecutor();......
  • springboot集成minIO
    文件系统:负责管理和存储文件的系统软件。操作系统通过文件系统提供的接口去存取文件,用户通过操作系统访问磁盘上的文件minIO:轻量级服务分布式文件系统,适合存储非机构化数据。采用去中心化共享架构,结点之间是对等关系。 端口号为9000,初次登录账号密码都是minioadmin minIO中......
  • Springboot+Vue加密通信
    前言本文旨在给出Springboot+Vue框架下的加密通信具体实现,同时为照顾非行业内/初学读者,第一小节浅显的解释下加解密方式,老鸟直接跳过。1加解密方式常见的加解密方式大概分成对称加密、非对称加密与信息摘要算法三类。下面仅从使用角度简单介绍下加解密方式:1.1对称......
  • springboot使用注解方式打印方法日志
    springboot使用注解方式打印方法日志,可以很方便的打印日志,通用性很强。耦合很低,很好。作为程序员的我不废话,咱们直接上代码先创建个注解@Target(ElementType.METHOD)@Retention(RetentionPolicy.RUNTIME)@Documentedpublic@interfaceShowLog{/***日志描......
  • springboot的MultipartFile转File读取
    在SpringBoot中,处理文件上传时,MultipartFile接口被用来封装上传的文件信息。如果需要将MultipartFile转换为Java标准的File对象进行读取。以下是具体的操作流程:1.创建临时文件        首先,需要将接收到的MultipartFile对象转换为一个临时File对象。      ......
  • springboot-mybatis-db2
    工程pom.xml文件增加如下依赖<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-jdbc</artifactId></dependency><dependency>&......
  • IPSEC在NAT场景中所遇到的问题
    一、实验拓扑二、基础配置如上图所示配置相应的接口地址和主机地址(此处省略..........)三、详细配置及结果验证(一)FW1和FW2通过IPSEC及NAT实现跨外网连接FW3防火墙NAT设置[FW3-address-group-NAT_POOL]disth#nataddress-groupNAT_POOL1 modeno-patglobal sec......
  • Sora技术如何革新教育领域:预测未来教育中的降AI率应用场景
    ​Sora——这个让人在24年初引爆AI圈的新产品,它究竟会如何改变我们的教育领域呢?从gpt到Sora,从对话型的ai到游戏和短剧制作的新风口,我们从23年到24年一个接一个地被震惊!Sora能够根据文本提示生成高质量的视频内容,这打开了一个全新的创意世界。对于教育行业来说,这意味着什么呢......