SpringBoot内部调用事务不起作用问题的解决方案

 更新时间:2019年10月10日 11:01:23   作者:平头哥的技术博文  
这篇文章主要介绍了SpringBoot事务不起作用问题的解决方案,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下

在做业务开发时,遇到了一个事务不起作用的问题。大概流程是这样的,方法内部的定时任务调用了一个带事务的方法,失败后事务没有回滚。查阅资料后,问题得到解决,记录下来分享给大家。

场景

我在这里模拟一个场景,大概的调用方式就如下面的代码这样。

  @Override
  @Transactional(rollbackFor = RuntimeException.class)
  public void insertUser(User user) {
    userMapper.insertUser(user);
    throw new RuntimeException("");
  }
  
  /**
   * 内部调用新增方法
   *
   * @param user
   */
  @Override
  public void invokeInsertUser(User user) {
    this.insertUser(user);
  }

原因

AOP使用的是动态代理的机制,它会给类生成一个代理类,事务的相关操作都在代理类上完成。内部方式使用this调用方式时,使用的是实例调用,并没有通过代理类调用方法,所以会导致事务失效。

解决办法

方法一 引入自身bean

在类内部通过@Autowired将本身bean引入,然后通过调用自身bean,从而实现使用AOP代理操作。

注入自身bean

  @Autowired
  @Lazy
  private UserService service;

修改invokeInsertUser方法

  /**
   * 解决方法一 在bean中将自己注入进来
   * @param user
   */
  @Override
  public void invokeInsertUser(User user) {
    this.service.insertUser(user);
  }

方法二 通过ApplicationContext引入bean

通过ApplicationContext获取bean,通过bean调用内部方法,就使用了bean的代理类。

注入ApplicationContext

  @Autowired
  ApplicationContext applicationContext;

修改invokeInsertUser方法

  /**
   * 解决方法二 通过applicationContext获取到bean
   * @param user
   */
  @Override
  public void invokeInsertUser(User user) {
    ((UserService)applicationContext.getBean("userService")).invokeInsertUser(user);
  }

方法三 通过AopContext获取当前类的代理类

通过AopContext获取当前类的代理类,直接通过代理类调用方法

在引导类上添加@EnableAspectJAutoProxy(exposeProxy=true)注解

修改invokeInsertUser方法

  /**
   * 解决方法三 通过applicationContext获取到bean
   *
   * @param user
   */
  @Override
  public void invokeInsertUser(User user) {
    ((UserService) AopContext.currentProxy()).invokeInsertUser(user);
  }

以上就是内部方法调用时,事务不起作用的原因及解决办法。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

相关文章

  • SpringBoot 集成 ShedLock 分布式锁的示例详解

    SpringBoot 集成 ShedLock 分布式锁的示例详解

    ShedLock是一个在分布式环境中使用的定时任务框架,用于解决在分布式环境中的多个实例的相同定时任务在同一时间点重复执行的问题,本文重点给大家介绍SpringBoot 分布式锁ShedLock的相关知识,感兴趣的朋友一起看看吧
    2021-08-08
  • Java Map 按照Value排序的实现方法

    Java Map 按照Value排序的实现方法

    Map是键值对的集合接口,它的实现类主要包括:HashMap,TreeMap,Hashtable以及LinkedHashMap等。这篇文章主要介绍了Java Map 按照Value排序的实现方法,需要的朋友可以参考下
    2016-08-08
  • IDEA 如何导入别人的javaweb项目进行部署

    IDEA 如何导入别人的javaweb项目进行部署

    这篇文章主要介绍了IDEA 如何导入别人的javaweb项目进行部署,本文给大家分享我的详细部署过程及遇到问题解决方法,需要的朋友可以参考下
    2023-03-03
  • Java中volatile关键字实现原理

    Java中volatile关键字实现原理

    本文详细解读一下volatile关键字如何保证变量在多线程之间的可见性,对Java中volatile关键字实现原理感兴趣的朋友一起通过本文学习吧
    2017-06-06
  • Java反射机制详解

    Java反射机制详解

    Java的反射机制是在运行状态中,对于任何一个类,都可以知道这个类的所有属性和方法,对于任何一个对象,都可以调用它所有的方法和属性,修改部分类型信息。本文就来详细讲讲Java反射机制的使用
    2022-07-07
  • java9学习系列之安装与jshell使用

    java9学习系列之安装与jshell使用

    2017年9月21日,千呼万唤始出来,Java9终于发布了。作为自己天天接触的“对象”,还是应该多花点心思去了解她。后续再进一步了解详细特性。下面这篇文章主要给大家介绍了关于java9学习系列之安装与jshell使用的相关资料,需要的朋友可以参考下。
    2017-09-09
  • Java实现银行ATM系统

    Java实现银行ATM系统

    这篇文章主要为大家详细介绍了Java实现银行ATM系统,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2020-04-04
  • JAVA获取CLASSPATH路径的方法详解

    JAVA获取CLASSPATH路径的方法详解

    这篇文章主要介绍了Java 中获取类路径 classpath 的方法,非常不错,具有参考借鉴价值,需要的朋友可以参考下
    2016-09-09
  • Spring自动装配Bean实现过程详解

    Spring自动装配Bean实现过程详解

    这篇文章主要介绍了Spring自动装配Bean实现过程详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-02-02
  • Java实现markdown格式内容转换为word

    Java实现markdown格式内容转换为word

    这篇文章主要为大家简单介绍了如何利用Java实现markdown格式内容转换为word文档,文中的示例代码简洁易懂,有需要的小伙伴可以参考一下
    2025-03-03

最新评论