Spring事务调用类自己方法失效解决办法和原因
问题
正常情况下,我们都是在controller里调用service里的方法,这个方法如果需要加事务,就在方法上加上@Transactional,这样是没问题的,事务会生效。
可是如果像下面这样,绕以下,service里方法调用了自己类的方法,这个时候即使加了@Transactional,事务也不会生效。
@Controller
public class TestController { @Autowired
private TestService testService; @GetMapping("/test")
public void test(){
testService.methodB();
} }
@Service
public class TestService { @Transactional
public void methodA(){ } /**
* 这里调用methodA() 的事务将会失效
*/
public void methodB(){
this.methodA();
} }
原因
因为,spring的事务实现是使用了代理类来实现,而这里的this.methodA(),并没有走TestService的代理类,所以事务会失效。
解决
方法1:把methodA()和methodB()分别放到不同的类里。
方法2:自己注入自己,用注入的实例调用
@Service
public class TestService { @Autowired
private TestService testService; @Transactional
public void methodA(){ } /**
* 这里调用methodA() 的事务将会生效
*/
public void methodB(){
testService.methodA();
} }
方法3:获取代理类,利用代理类调用自己类的方法
@Service
public class TestService { @Transactional
public void methodA(){ } /**
* 这里调用methodA() 的事务将会生效
*/
public void methodB(){
((TestService)AopContext.currentProxy()).methodA();
} }
最后
spring的aop代理有jdk代理和cglib代理实现,具体参阅java中代理,静态代理,动态代理以及spring aop代理方式,实现原理统一汇总
//是否代理对象
AopUtils.isAopProxy(AopContext.currentProxy()); //是否cglib 代理对象
AopUtils.isCglibProxy(AopContext.currentProxy()); //是否jdk动态代理
AopUtils.isJdkDynamicProxy(AopContext.currentProxy());
Spring事务调用类自己方法失效解决办法和原因的更多相关文章
- iOS:didSelectRowAtIndexPath:方法失效解决办法
问题描述及解决过程: 为了达到点击TableView空白区退出键盘的效果,给控制器注册了一个UITapGestureRecognizer来识别点击事件,代码如下: #pragma mark - 设置手 ...
- C++ 11 线程调用类的成员函数解决办法
在C++中,_beginthreadex 创建线程是很麻烦的.要求入口函数必须是类的静态函数. 通常,可以采用thunk,或者模板来实现. 因C++ 11中引入了 std::async ,可以很好的解 ...
- 一个页面上调用多个setInterval失效解决办法(使用于同一时间间隔)
将方法封装在一起,只调用一个setInterval window.setInterval( function () { $.ajax({ type: "GET", url: '/M ...
- Android开发教程 - 使用Data Binding Android Studio不能正常生成相关类/方法的解决办法
本系列目录 使用Data Binding(一)介绍 使用Data Binding(二)集成与配置 使用Data Binding(三)在Activity中的使用 使用Data Binding(四)在Fr ...
- Java动态调用类中方法
在Java中,调用类的方法有两种方式:对于静态方法可以直接使用类名调用,对于非静态方法必须使用类的对象调用.反射机制提供了比较另类的调用方式,可以根据需要指定要调用的方法,而不必在编程时确定.调用的方 ...
- C#通过反射调用类及方法
反射有个典型的应用,就是菜单的动态加载,原理就是通过反射调用某个窗体(类).下面演示一下通过反射调用类及方法: 1.新建一个类,命名为:ReflectionHelper,代码如下: #region 创 ...
- 基于Spring框架的简单多数据源切换解决办法
基于Spring框架的简单多数据源切换解决办法 Spring框架JDBC包提供了一个抽象类AbstractRoutingDataSource提供了动态切换数据库的基础方法.我们仅仅需要实现一个简单的数 ...
- Xcode升级插件失效解决办法-升级版
Xcode升级插件失效解决办法 每每升级Xcode,第三方插件总是中枪.解决办法也基本是依据http://joeshang.github.io/2015/04/10/fix-xcode-upgrade ...
- MySQL ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: NO) 的解决办法和原因
这两天下载了MySQL5.7.11进行安装,发现到了初次使用输入密码的时候,不管怎样都进不去,即使按照网上说的在mysqld 下面添加skip-grant-tables也是不行,后来研究了两天,终于找 ...
随机推荐
- mysql建表中auto_increment=21
CREATE TABLE `demo` ( `id` ) NOT NULL AUTO_INCREMENT, `img` ) DEFAULT NULL COMMENT '大图', `status` ) ...
- 使用 Floccus 插件和坚果云同步 Chrome 类浏览器书签
使用 Floccus 插件和坚果云同步 Chrome 类浏览器书签 魏刘宏 2019 年 11 月 22 日 如题,本文讨论在使用 Chromium 内核的浏览器上,使用 Floccus 插件,配合 ...
- JS运算符类型
一.运算符类型 1.算术运算符: 用于各类数值运算,包括加(+).减(-).乘(*).除(/).求余(或称模运算,%).自增(++).自减(--)共七种. 2.关系运算符: 用于比较运算.包括大于(& ...
- warning: Unexpected unnamed function (func-names)
warning: Unexpected unnamed function (func-names) 看到这个提示基本是就是说你的函数不能是匿名函数,最好可以起一个名字,然后你增加一个函数名称就好了 R ...
- JavaWeb项目——博客系统
系统介绍 博客是互联网平台上的个人信息交流中心.通常博客就是用来发表文章,所有的文章都是按照年份和日期排列,有些类似斑竹的日记.看上去平淡无奇,毫无可炫耀之处,但它可以让每个人零成本.零维护地创建自己 ...
- Scrum冲刺第四篇
一.每日例会 会议照片 成员 昨日已完成的工作 今日计划完成的工作 工作中遇到的困难 陈嘉欣 撰写博客,管理成员提交代码 和队友一同开发音乐控制模块 对音频控制方面知识了解少,功能实现困难 邓镇港 帮 ...
- requests---自动写博客
前两天写过一个关于session的博客,session登录过后,可以进行一系列的操作,今天通过模拟登录博客园,自动写博客 自动写博客 我们先理下书写的思路: 1.通过request访问博客园: 2.通 ...
- 目标检测论文解读1——Rich feature hierarchies for accurate object detection and semantic segmentation
背景 在2012 Imagenet LSVRC比赛中,Alexnet以15.3%的top-5 错误率轻松拔得头筹(第二名top-5错误率为26.2%).由此,ConvNet的潜力受到广泛认可,一炮而红 ...
- 4-剑指offer: 把数组排成最小的数
题目描述 输入一个正整数数组,把数组里所有数字拼接起来排成一个数,打印能拼接出的所有数字中最小的一个.例如输入数组{3,32,321},则打印出这三个数字能排成的最小数字为321323. 代码: cl ...
- google v8
https://github.com/tongbai168/v8 https://iwebing.lofter.com/tag/chromium 编译动态库 gyp mylib.gyp --dept ...