关于SpringBoot中事务失效的几种情况

 更新时间:2023年08月02日 11:37:31   作者:Eocc  
这篇文章主要介绍了关于SpringBoot中事务失效的几种情况,Spring AOP默认使用动态代理,会给被代理的类生成一个代理类,事务相关的操作都通过代理来完成,使用内部方法调用时,使用的是实例调用,没有通过代理类调用方法,因此事务不会检测到失败,需要的朋友可以参考下

内部调用

使用一个没有事务的方法调用一个有事务的方法,失败后不会进行回滚:

@Transactional
public int update(Admin admin) {
    int update = mapper.update(admin);
    return update;
}
public int invokeUpdate(Admin admin) {
    return update(admin);
}

这时因为Spring AOP默认使用动态代理,会给被代理的类生成一个代理类,事务相关的操作都通过代理来完成,使用内部方法调用时,使用的是实例调用,没有通过代理类调用方法,因此事务不会检测到失败。

解决方法就是使用代理类调用事务方法:

  • 在类内部注入本类
@Autowired
private AdminService service;
// 然后再调用
public int invokeUpdate(Admin admin) {
    return service.update(admin);
}
  • 通过ApplicationContext引入
((AdminService)ApplicationContext.getBean("adminService")).invokeUpdate(Admin admin);
  • 通过AopContext引入
((AdminService)AopContext.currentProxy()).invokeUpdate(Admin admin);

没有指定监听的Exception

@Transactional只会监听RuntimeException,当抛出其他异常时,不能正常捕获,也就不会回滚。

解决方法:

  1. 手动捕获异常,然后包装为RuntimeException抛出
  2. 使用roobackFor属性指定需要捕获的异常:
@Transactional(rollbackFor = Exception.class)
public int update(Admin admin) {
    int update = mapper.update(admin);
    return update;
}

内部异常被catch

源码:

org.springframework.transaction.interceptor.TransactionAspectSupport#invokeWithinTransaction

关键部分:

 try {
     //开启事务
     //这个地方也可以看出是通过代理来实现的事物,如果绕过代理调用(如内部调用),则不会开启事务
     Object var8 = invocation.proceedWithInvocation();
     return var8;
 } catch (Throwable var13) {
     //如果抛出异常,回滚事务
     //如果异常在方法内部被catch了,这个地方就不会接收到异常,就不会回滚事务
     if (txAttr.rollbackOn(var13)) {
         if (var13 instanceof RuntimeException) {
             throw (RuntimeException)var13;
         }
         throw new TransactionAspectSupport.ThrowableHolderException(var13);
     }
     throwableHolder.throwable = var13;
     var9 = null;
 } finally {
     //提交事务
     this.cleanupTransactionInfo(txInfo);
 }

到此这篇关于关于SpringBoot中事务失效的几种情况的文章就介绍到这了,更多相关SpringBoot事务失效内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • spring boot mybatis枚举映射示例代码

    spring boot mybatis枚举映射示例代码

    这篇文章主要给大家介绍了关于spring boot mybatis枚举映射的相关资料,文中通过示例代码介绍的非常详细,对大家学习或者使用Spring Boot具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧
    2019-09-09
  • Springboot 整合shiro实现权限控制的方法

    Springboot 整合shiro实现权限控制的方法

    这篇文章主要介绍了Springboot 整合shiro实现权限控制的相关知识,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-11-11
  • Java内存模型可见性问题相关解析

    Java内存模型可见性问题相关解析

    这篇文章主要介绍了Java内存模型可见性问题相关解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2019-12-12
  • Mybatis日志配置方式(slf4j、log4j、log4j2)

    Mybatis日志配置方式(slf4j、log4j、log4j2)

    这篇文章主要介绍了Mybatis日志配置方式(slf4j、log4j、log4j2),具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2023-09-09
  • Java 中 Reference用法详解

    Java 中 Reference用法详解

    这篇文章主要介绍了Java 中 Reference用法详解的相关资料,需要的朋友可以参考下
    2017-03-03
  • 深入解析Java编程中的boolean对象的运用

    深入解析Java编程中的boolean对象的运用

    这篇文章主要介绍了Java编程中的boolean对象的运用,是Java入门学习中的基础知识,需要的朋友可以参考下
    2015-10-10
  • 看过就懂的java零拷贝及实现方式详解

    看过就懂的java零拷贝及实现方式详解

    这篇文章主要为大家详细的介绍了什么是零拷贝,传统的IO执行流程,零拷贝相关的知识点回顾,零拷贝实现的几种方式及java提供的零拷贝方式相关内容,有需要的朋友可以借鉴参考下
    2022-01-01
  • SpringBoot+Redis+Lua分布式限流的实现

    SpringBoot+Redis+Lua分布式限流的实现

    本文主要介绍了SpringBoot+Redis+Lua分布式限流的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2022-08-08
  • SpringBoot整合Zookeeper详细教程

    SpringBoot整合Zookeeper详细教程

    Curator是Netflix公司开源的⼀套zookeeper客户端框架,Curator是对Zookeeper⽀持最好的客户端框架。Curator封装了⼤部分Zookeeper的功能,⽐如Leader选举、分布式锁等,减少了技术⼈员在使⽤Zookeeper时的底层细节开发⼯作
    2022-12-12
  • java中对象的强、软、弱、虚四种引用详解

    java中对象的强、软、弱、虚四种引用详解

    这篇文章主要介绍了java中对象的强、软、弱、虚四种引用详解,对象的引用分为4种,分别是强引用>软引用>弱引用>虚引用,程序员可以通过不同的引用控制对象的生命周期,方便垃圾回收,使程序更加灵活的控制对象生命周期,需要的朋友可以参考下
    2023-09-09

最新评论