SpringBoot 异常回滚 事务的使用___Springboot @Transactional 事务不回滚

Springboot中事务的使用:

1、启动类加上@EnableTransactionManagement注解,开启事务支持(其实默认是开启的)。

2、在使用事务的public(只有public支持事务)方法(或者类-相当于该类的所有public方法都使用)加上@Transactional注解。

在实际使用中一般是在service中使用@Transactional,那么对于controller->service流程中:

如果controller未开启事务,service中开始了事务,service成功执行,controller在之后的运行中出现异常(错误),不会自动回滚。

也就是说,只有在开启事务的方法中出现异常(默认只有非检测性异常才生效-RuntimeException )(错误-Error)才会自动回滚。

如果想要对抛出的任何异常都进行自动回滚(而不是只针对RuntimeException),只需要在使用@Transactional(rollbackFor = Exception.class)即可。

开启事务的方法中事务回滚的情况:

①未发现的异常,程序运行过程中自动抛出RuntimeException或者其子类,程序终止,自动回滚。

②使用TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();进行手动回滚。

③注意:如果在try-catch语句中对可能出现的异常(RuntimeException)进行了处理,没有再手动throw异常,spring认为该方法成功执行,不会进行回滚,此时需要调用②中方法进行手动回滚 (java 框架项目案例:www.fhadmin.org)

另外,如果try-catch语句在finally中进行了return操作,那么catch中手动抛出的异常也会被覆盖,同样不会自动回滚。

//不会自动回滚
try{throw new RuntimeException();
}catch(RuntimeException e){e.printStackTrace();
}finally{}
//会自动回滚
try{throw new RuntimeException();
}catch(RuntimeException e){e.printStackTrace();throw new RuntimeException();
}finally{}



Springboot @Transactional 事务不回滚

一、异常捕获的原因

  1. 这里Exception异常,他又分为运行时异常RuntimeException和非运行时异常
  2. 可查的异常(checked exceptions):Exception下除了RuntimeException外的异常
  3. 不可查的异常(unchecked exceptions):RuntimeException及其子类和错误(Error)
  4. 异常checked例外也回滚:在整个方法前加上 @Transactional(rollbackFor=Exception.class)
  5. 异常unchecked例外不回滚: @Transactional(notRollbackFor=RunTimeException.class)
  6. 如果异常被try{}catch{}了,事务就不回滚了,如果想让事务回滚必须再往外抛try{}catch{throw Exception}

二、数据库引擎不支持回滚(使用MYSQL就很可能是这个原因)

  1. Mysql数据库有两种引擎,注意要使用支持事务的引擎,比如innodb,如果是MyISAM,事务是不起作用的。

  2. 使用springboot的jpa自动创建库表的时候,默认使用MyISAM引擎,可以检查库表查看引擎。

  3. 修改配置:

    spring:  jpa:hibernate:ddl-auto: updatenaming:physical-strategy: org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl #按字段名字建表show-sql: truedatabase: mysqldatabase-platform: org.hibernate.dialect.MySQL5InnoDBDialect  #使用innodb引擎建表
    

三、发生了自调用情况

spring的数据库事务调用的实现原理是AOP,而AOP的原理是动态代理,在自调用的过程中,是类自身的调用,而不是代理对象去调用,那么不会产生AOP,没有AOP,意味着@Transactional不会被切面捕获,这样spring就不能把你的代码植入到约定的流程中,于是就产生了事务回滚失败。

解决方案:

1、将涉及到事务的处理都放入一个方法中,由其他类调用。

2、如果非要在本类中调用,那么需要在本类中生成本类的bean对象,由这个bean对象来调用,实现方式也有多种:

  • 自注入
  • 通过SpringContextHolder获取bean,即注入ApplicationContext,从ApplicationContext获取bean
  • 通过AopContext获取当前类的代理对象,注意此种方式需要开启expose-proxy=“true”,可通过注解开启@EnableAspectJAutoProxy(exposeProxy =true)

最后一种方式的伪代码:

@Service
public class OrderService {public void insert() {OrderService proxy = (OrderService) AopContext.currentProxy();proxy.insertOrder();}@Transactionalpublic void insertOrder() {//SQL操作}
}

[

因为AopContext默认是不暴露当前代理类的,所以要@EnableAspectJAutoProxy(exposeProxy =true)或者<aop:aspectj-autoproxy expose-proxy=“true”/>:

四、补充:

在Spring 的AOP实现有两种代理方式:

  • Java动态代理 :通过反射生成一个实现了代理方法的匿名类来完成代理
  • cglib代理 :通过Asm修改字节码文件,生成一个子类来完成代理

Spring在项目中会根据被代理对象是否实现了接口来自动切换上述两种代理方式

所以private方法也不能实现事务

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/556005.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

简述网络调研的作用_利用龙伯球透镜天线提升高铁4G网络覆盖

透镜天线&#xff0c;一种能够通过电磁波&#xff0c;将点源或线源的球面波或柱面波转换为平面波从而获得笔形、扇形或其他形状波束的天线。通过合适设计透镜表面形状和折射率 n&#xff0c;调节电磁波的相速以获得辐射口径上的平面波前。透镜天线吸收了许多光信息工程技术&…

脚手架 插件

一、定义插件 plugin.js --> export default{} --> install() --> // 全局过滤器 Vue.filter(myFilter, function (value) {return value.slice(0, 4); });// 全局指令 Vue.directive("fbind", {bind(element, binding) {element.value binding.value;},i…

SQLIntegrityConstraintViolationException: 异常解决

SQLIntegrityConstraintViolationException: Duplicate entry ‘xxx’ for key yyyzzz’异常解决 一. 异常现象 在做Java Web项目操作数据库添加数据的时候&#xff0c;突然发现曝出如下图所示异常&#xff1a; Caused by: java.sql.SQLIntegrityConstraintViolationExceptio…

scoped 样式

一、加不加 scoped &#xff1f; 加上之后&#xff0c;让样式在局部生效&#xff0c;防止冲突 <!-- a.vue --> <style lang"less" scoped> #bg-red {background-color: #f00; } </style>不加&#xff0c;相当于是定义的全局样式&#xff0c;每个…

一步怎么测量图片_测量不容易?15套测量仪器实操手册+自动计算表格,自学也可以...

测量不容易&#xff1f;15套测量仪器实操手册自动计算表格&#xff0c;自学也可以很多施工羡慕测量工资高&#xff0c;但是测量工资高也就意味着责任大&#xff0c;施工在休息的时候测量就下工地了&#xff0c;施工聚会的时候&#xff0c;测量在埋头苦算。如果施工想要干测量该…

controller的异常处理以及service层的事务控制___controller层 trycatch不影响service层抛出的异常

controller的异常处理以及service层的事务控制 最近写代码涉及到一些事务&#xff0c;上午终于把代码给理顺了&#xff0c;之前不太清楚在哪里做异常处理&#xff0c;导致代码遍地try-catch&#xff0c;相当难看。 还是基于controller-service-dao三层来写代码&#xff0c;从…

Java 中判断一个字符串是否包含另外一个字符串的方法

方法一&#xff1a;indexOf(String s) 可以配合indexOf(String s)的使用&#xff0c;如果包含&#xff0c;返回的值是包含该子字符串在父类字符串中起始位置&#xff1b;如果不包含必定全部返回值为-1 public void test02() {String str1"张三";String str2"是…

速看!销冠高效给客户群发消息的秘诀

你是不是也有过这样的疑问&#xff1a;明明都是给客户群发消息&#xff0c;为什么别人的成交率那么高&#xff0c;自己却效果一般呢&#xff1f; 今天就给大家分享销冠常用的高效群发消息秘诀&#xff0c;让大家都能更好地与客户进行沟通&#xff0c;提高成交率&#xff01; …

不显示_电脑不显示桌面图标怎么办?

在现在这个社会时代中&#xff0c;人们对电脑的使用频率非常的高&#xff0c;电脑可以说已经成为了大家在生活中不可或缺的必备品。但是在使用电脑过程中的时候也都容易出现故障。那么&#xff0c;若碰上 电脑开机后只显示桌面的背景而没有任何程序和应用的情况&#xff0c;莫急…

Xshell 的基本使用

软件长这样 Xshell 链接地址 一、输入 ifconfig 查看 linux ip 地址 二、远程连接服务器 三、测试连接

Java中String类的concat方法___java的String字符串的concat()方法连接字符串和“+“连接字符串解释

Java中String类的concat方法 在了解concat&#xff08;&#xff09;之前&#xff0c;首先需要明确的是String的两点特殊性。 长度不可变值不可变 这两点从源码中对String的声明可以体现&#xff1a; private final char[] value ;其中final对应值的不可更改的特性&#xff1b…

大于小于优化_架构 - 以MySQL为例,详解数据库索引原理及深度优化

一、摘要本文以MySQL数据库为研究对象&#xff0c;讨论与数据库索引相关的一些话题。特别需要说明的是&#xff0c;MySQL支持诸多存储引擎&#xff0c;而各种存储引擎对索引的支持也各不相同&#xff0c;因此MySQL数据库支持多种索引类型&#xff0c;如BTree索引&#xff0c;哈…

Xftp 基本使用

vmware tool 安装 连接终端Xshell5_安装vmtools_

MySQL:日期函数、时间函数总结

MySQL 获得当前日期时间 函数 获得当前日期时间&#xff08;date time&#xff09;函数&#xff1a;now() mysql> select now();--------------------- | now() | --------------------- | 2008-08-08 22:20:46 | ---------------------获得当前日期时间&#xff08;date…

Vue 组件的自定义事件

绑定自定义事件 // 第一种方式 <Demo demo"test"/> || <Demo v-on:demo"test"/>// 第二种方式 <Demo ref"demo"/> ... mounted() {this.$refs.xxx.$on(demo, this.test) } // 如果想自定义事件只能触发一次&#xff0c;可以使…

c++byte数组和文件的相互转换_终于!word、excel、ppt文件相互转换技巧来了!

不知道大家在用Office软件的时候&#xff0c;有没有遇到过这样的问题。做了个Word文档总结&#xff0c;却需要转换成PPT上台汇报&#xff1b;做了个Word表格统计&#xff0c;却需要转换成Excel进行分析&#xff1b;做了个Excel图表分析&#xff0c;却需要放到Word或PPT上&#…

全局事件总线 (GlobalEventBus)

一、一种组件间通信的方式&#xff0c;适用于任意组件间通信。 二、建立 bus&#xff1a; Vue.prototype.bus new Vue();三、使用 bus bus 上注册自定义事件 this.bus.$emit(customEvent, params);任意组件监听 this.bus.$on(customEvent, function (params) {console.log…

java多线程之ThreadLoal详解

一、ThreadLocal简介 多线程访问同一个共享变量时特别容易出现并发问题&#xff0c;特别是在多个线程需要对一个共享变量进行写入时。为了保证线程安全&#xff0c;一般使用者在访问共享变量时需要进行适当的同步 同步一般是通过加锁来实现的,但这对用户有一定要求,加重了使用…

python 心电处理包_python 黏包现象及其解决方案

一、数据缓冲区缓冲区(buffer)&#xff0c;它是内存空间的一部分。也就是说&#xff0c;在内存空间中预留了一定的存储空间&#xff0c;这些存储空间用来缓冲输入或输出的数据&#xff0c;这部分预留的空间就叫做缓冲区&#xff0c;显然缓冲区是具有一定大小的。二、为什么要缓…

消息订阅与发布(pubsub)

一、一种组件间通信的方式&#xff0c;适用于任意组件间通信。 二、使用步骤&#xff1a; 安装 pubsub&#xff1a;npm i pubsub-js引入&#xff1a;import pubsub from pubsub-js接收数据&#xff1a;A组件想接收数据&#xff0c;则在A组件中订阅消息&#xff0c;订阅的回调在…