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

场景

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


@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);
}

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

最后

打个小广告,金九银十跳槽季,平头哥给大家整理了一份较全面的 Java 学习资料,欢迎扫码关注微信公众号:「平头哥的技术博文」领取,祝各位升职加薪。

SpringBoot 内部方法调用,事务不起作用的原因及解决办法的更多相关文章

  1. jquery ajax success 函数 异步调用方法中不能给全局变量赋值的原因及解决办法

    jquery ajax success 函数 异步调用方法中不能给全局变量赋值的原因及解决办法   在调用一个jquery的ajax方法时我们有时会需要该方法返回一个值或者给某个全局变量赋值,可是我们 ...

  2. spring声明式事务 同一类内方法调用事务失效

    只要避开Spring目前的AOP实现上的限制,要么都声明要事务,要么分开成两个类,要么直接在方法里使用编程式事务 [问题] Spring的声明式事务,我想就不用多介绍了吧,一句话“自从用了Spring ...

  3. spring声明式事务 同一类内方法调用事务失效(转)

    原文 https://blog.csdn.net/jiesa/article/details/53438342 [问题] Spring的声明式事务,我想就不用多介绍了吧,一句话“自从用了Spring ...

  4. Spring的Bean内部方法调用无法使用AOP切面(CacheAble注解失效)

    Spring的Bean内部方法调用无法使用AOP切面(CacheAble注解失效) 前言 今天在使用Spring cache的Cacheable注解的过程中遇见了一个Cacheable注解失效的问题, ...

  5. C# WebAPI中DateTime类型字段在使用微软自带的方法转json格式后默认含T的解决办法

    原文:C# WebAPI中DateTime类型字段在使用微软自带的方法转json格式后默认含T的解决办法 本人新手,在.Net中写WebAPI的时候,当接口返回的json数据含有日期时间类型的字段时, ...

  6. SpringBoot整合Swagger2案例,以及报错:java.lang.NumberFormatException: For input string: ""原因和解决办法

    原文链接:https://blog.csdn.net/weixin_43724369/article/details/89341949 SpringBoot整合Swagger2案例 先说SpringB ...

  7. Spring AOP无法拦截内部方法调用

    当在同一个类中,A方法调用B方法时,AOP无法工作的问题 假设一个接口里面有两个方法: package demo.long; public interface CustomerService { pu ...

  8. Spring 内部方法调用失效问题(AOP)

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

  9. AOP方法增强自身内部方法调用无效 SpringCache 例子

    开启注解@EnableCaChing,配置CacheManager,结合注解@Cacheable,@CacheEvit,@CachePut对数据进行缓存操作 缺点:内部调用,非Public方法上使用注 ...

随机推荐

  1. 【NOIP2015】扫雷游戏-C++

    描述 扫雷游戏是一款十分经典的单机小游戏.在 n 行 m 列的雷区中有一些格子含有地雷 (称之为地雷格),其他格子不含地雷(称之为非地雷格).玩家翻开一个非地雷格时, 该格将会出现一个数字--提示周围 ...

  2. Excel催化剂开源第11波-动态数组函数技术开源及要点讲述

    在Excel催化剂中,大量的自定义函数使用了动态数组函数效果,虽然不是原生的Excel365版效果(听说Excel2019版取消了支持动态数组函数,还没求证到位,Excel365是可以用,但也仅限于部 ...

  3. python面向过程编程小程序 -ATM(里面用了终端打印)

    06.09自我总结 1.文件摆放 ├── xxxx │ ├── run.py │ └── fil_mode.py │ └── data_time.py │ └── loading.py │ └── d ...

  4. On The Way—Step 2 Python入门之Python内容初始

    2.1 输出 print() ​ 打印一个字符串 print('你真好!') ​ 打印变量内容 a = '你真好!' print(a) 结果都是:你真好! 2.2 变量 变量名字规则 只能用下划线.字 ...

  5. 1.4.2python网站地图爬虫(每天一更)

    # -*- coding: utf-8 -*- ''' Created on 2019年5月6日 @author: 薛卫卫 ''' import urllib.request import re de ...

  6. Linux学习笔记04

    文件查找命令find 文件查找命令: which locate find which:查找命令字所在的位置 locate:模糊匹配(只要包含关键字的文件都查找出来) 不是实时的,基于数据库查找, up ...

  7. Linux学习笔记03

    一.Linux常见命令 file:查看文件类型(windows用扩展名识别文件类型) 语法:file [options] [args] -b:显示结果时,不显示文件名 -c:显示执行file命令的执行 ...

  8. Thymeleaf 模板 springboot集成使用

    一.Thymeleaf是什么? 简单说, Thymeleaf 是一款用于渲染XML/XHTML/HTML5内容的模板引擎,类似我之前用过的FreeMarker .由于它支持 html 原型,然后在 h ...

  9. 用scrapy爬取搜狗Lofter图片

    用scrapy爬取搜狗Lofter图片 # -*- coding: utf-8 -*- import json import scrapy from scrapy.http import Reques ...

  10. Android 虹软人脸识别SDK-人脸对比

    准备 : 登录官方网站,获取SDK,进行个人验证后新建项目,获取APP_ID,和SDK_KEY: https://ai.arcsoft.com.cn/ucenter/resource/build/in ...