首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

当我在Spring @Transactional内部调用一个方法时,它不起作用。我怎么才能解决它呢?

在Spring中,@Transactional注解用于实现事务管理。当在@Transactional注解标记的方法内部调用另一个方法时,事务可能不会起作用的原因是因为Spring的事务机制是基于代理模式实现的。

解决这个问题的方法有两种:

  1. 将@Transactional注解放在类级别上:将@Transactional注解放在类级别上,而不是方法级别上。这样做可以确保整个类的所有方法都受到事务管理的影响。例如:
代码语言:txt
复制
@Transactional
public class MyClass {
    public void method1() {
        // ...
        method2();
        // ...
    }

    public void method2() {
        // ...
    }
}
  1. 通过AopProxyUtils.ultimateTargetClass方法获取目标类的实例:在方法内部调用另一个方法时,Spring可能会创建一个代理对象来管理事务。为了确保事务起作用,可以使用AopProxyUtils.ultimateTargetClass方法获取目标类的实例,并调用目标类的方法。例如:
代码语言:txt
复制
@Service
public class MyService {
    @Autowired
    private MyDao myDao;

    @Transactional
    public void method1() {
        // ...
        MyService target = AopProxyUtils.ultimateTargetClass(this);
        target.method2();
        // ...
    }

    public void method2() {
        // ...
    }
}

这样做可以绕过代理对象,直接调用目标类的方法,确保事务起作用。

以上是解决在Spring @Transactional内部调用方法时事务不起作用的两种方法。希望对你有帮助!

页面内容是否对你有帮助?
有帮助
没帮助

相关·内容

【小家java】Spring事务不生效的原因大解读

接口上使用 @Transactional 注解,只能当你设置了基于接口的代理才生效。...需要改成InnoDB才能支持 **原因二:**入口的方法必须是public,否则事务不起作用(这一点由Spring的AOP特性决定的,理论上而言,不public也能切入,但spring可能是觉得private...所以一个类中一个无事务的方法调用一个有事务的方法,事务是不会起作用的(这就是业界老问题:类内部方法调用事务不生效的问题原因)。 ? 图二:事务生效 ?...图五:事务生效(稍微解释一下,这里虽然是方法内部调用,但是事务切入了addInfo方法,所以即使内部抛出异常,也是可以生效的。当年竟然惊讶,看来还是太年轻,哈哈) ?...这里必须说几句:这是我们解决方法内部调用事务不生效的最常用方法之一:内部维护一个注入自己的Bean,然后使用这个属性来调用方法

3K30

拜托,被再让优化大事务了,的头都裂了

项目顺利上线后,专门抽了一个迭代的时间去解决大事务问题,目前已经优化完成,并且顺利上线。现给大家总结了一下,我们当时使用的一些解决办法,以便大家被相同问题困扰,可以参考一下。...@Transactional注解一般加在某个业务方法上,会导致整个业务方法都在同一个事务中,粒度太粗,不好控制事务范围,是出现大事务问题的最常见的原因。 那我们该怎么?...注解,该怎么拆分?...因为@Transactional注解的声明式事务是通过spring aop起作用的,而spring aop需要生成代理对象,直接方法调用使用的还是原始对象,所以事务不会生效。...其实spring ioc内部的三级缓存保证了,不会出现循环依赖问题。如果你想进一步了解循环依赖问题,可以看看我之前文章《spring解决循环依赖为什么要用三级缓存?》。

64010

让人头痛的大事务问题到底要如何解决

项目顺利上线后,专门抽了一个迭代的时间去解决大事务问题,目前已经优化完成,并且顺利上线。现给大家总结了一下,我们当时使用的一些解决办法,以便大家被相同问题困扰,可以参考一下。...@Transactional注解一般加在某个业务方法上,会导致整个业务方法都在同一个事务中,粒度太粗,不好控制事务范围,是出现大事务问题的最常见的原因。 那我们该怎么?...注解,该怎么拆分?...因为@Transactional注解的声明式事务是通过spring aop起作用的,而spring aop需要生成代理对象,直接方法调用使用的还是原始对象,所以事务不会生效。...其实spring ioc内部的三级缓存保证了,不会出现循环依赖问题。如果你想进一步了解循环依赖问题,可以看看我之前文章《spring解决循环依赖为什么要用三级缓存?》。

85020

SpringBoot 中 AOP 的内部调用陷阱!

调用了同一个内部的 SomeService.test() 方法。...Spring AOP 并不是扩展了一个类(目标对象),而是使用了一个代理对象来包装目标对象,并拦截目标对象的方法调用。...这样的实现带来的影响是: 目标对象中调用自己类内部实现的方法,这些调用并不会转发到代理对象中,甚至代理对象都不知道有此调用的存在。...所自动实例化的一个代理对象,当调用 hello() 方法,先进入到此代理对象的同名方法中,然后代理对象中执行 AOP 逻辑(因为 hello 方法并没有注入 AOP 横切逻辑,因此调用它不会有额外的事情发生...,和 this 引用所指向的对象并不是同一个对象),因此我们 hello 方法调用中,使用 self.test() 的方式来调用 test() 方法,这样就会触发 AOP 逻辑了。

44720

公司新来一个同事,把 @Transactional 事务注解运用得炉火纯青。。

Transactional注解的方法中,再调用本类中的其他方法method2,那么method2方法上的@Transactional注解是不!...那么继续调用本类中其他方法是怎样,如下图: 可见目标对象内部的自我调用,也就是通过this.指向的目标对象将不会执行方法的增强。...下面来解决一下第一点的问题,如何在方法调用本类中其他方法。 通过AopContext.currentProxy ()获取到本类的代理对象,再去调用就好啦。...那么有人可能会有疑问了,方法1和方法2上都加@Transactional注解?答案是结果和上面是一致的。...如果想要方法1和方法2均单独保持事务一致性怎么,刚说过了,如果不是用代理调用@Transactional注解是不生效的,所以一定要使用代理调用实现,然后让方法1和方法2分别单独开启新的事务,便OK啦

40740

如何将 @Transactional 事务注解运用到炉火纯青?

哈哈~ 第一点要注意的就是@Transactional注解的方法中,再调用本类中的其他方法method2,那么method2方法上的@Transactional注解是不!会!生!效!的!...那么继续调用本类中其他方法是怎样,如下图: 可见目标对象内部的自我调用,也就是通过this.指向的目标对象将不会执行方法的增强。 先说第二点需要注意的地方,等下说如何解决上面第一点的问题。...service层,加了注解也一样不起作用吧,这个懒了,没有测试,其一是因为没有人会这么开发吧,其二是就认为是不起作用的,哈哈 下面来解决一下第一点的问题,如何在方法调用本类中其他方法。...那么有人可能会有疑问了,方法1和方法2上都加@Transactional注解?答案是结果和上面是一致的。...如果想要方法1和方法2均单独保持事务一致性怎么,刚说过了,如果不是用代理调用@Transactional注解是不生效的,所以一定要使用代理调用实现,然后让方法1和方法2分别单独开启新的事务,便OK啦

27750

每日一博 - 常见的Spring事务失效&事务不回滚案例集锦

文章目录 事务不生效 方法内部调用 修复方法一 : 【新加一个Service方法】 修复方法二:【该Service类中注入自己】 修复方法三:【通过AopContent类】<---- 推荐 访问权限问题...大事务问题 小结 ---- 事务不生效 方法内部调用 有时候我们需要在某个Service类的某个方法中,调用另外一个事务方法 @Service public class UserService {...由此可见,一个类中的方法直接内部调用,会导致事务失效。 那么问题来了,如果有些场景,确实想在同一个类的某个方法中,调用它自己的另外一个方法,该怎么?...,但是事务方法doOtherThing是另外一个线程中调用的。...因为doOtherThing方法出现了异常,没有手动捕获,会继续往上抛,到外层add方法的代理方法中捕获了异常。所以,这种情况是直接回滚了整个事务,不只回滚单个保存点。 怎么才能只回滚保存点

1.3K10

Java的@Transactional事务回滚

@Transactional 基本原理概述 应用系统调用声明@Transactional 的目标方法Spring Framework 默认使用 AOP 代理,代码运行时生成一个代理对象,根据@Transactional...2、对非检查型异常可以不用捕获,而检查型异常必须用try语句块进行处理或者把异常交给上级方法处理,总之就是必须写代码处理。所以必须service捕获异常,然后再次抛出,这样事务才能生效。...3.当然可以接口上使用 @Transactional 注解,但是这将只能当你设置了基于接口的代理才生效。...4.避免 Spring 的 AOP 的自调用问题:自调用就是方法A内调用本类的另一个加上事务注解的方法B方法B中对数据库的操作是不带事务的。...若同一类中的其他没有@Transactional 注解的方法内部调用有@Transactional 注解的方法,有@Transactional 注解的方法的事务被忽略,不会发生回滚。

2K30

聊聊spring事务失效的12种场景,太坑了

由此可见,一个类中的方法直接内部调用,会导致事务失效。 那么问题来了,如果有些场景,确实想在同一个类的某个方法中,调用它自己的另外一个方法,该怎么?...其实spring ioc内部的三级缓存保证了,不会出现循环依赖问题。但有些坑,如果你想进一步了解循环依赖问题,可以看看我之前文章《spring是如何解决循环依赖的?》。...add中,调用了事务方法doOtherThing,但是事务方法doOtherThing是另外一个线程中调用的。...因为doOtherThing方法出现了异常,没有手动捕获,会继续往上抛,到外层add方法的代理方法中捕获了异常。所以,这种情况是直接回滚了整个事务,不只回滚单个保存点。 怎么才能只回滚保存点?...这样就能保证,如果内部嵌套事务中出现异常,只回滚内部事务,而不影响外部事务。 三 其他 1 大事务问题 使用spring事务,有个让人非常头疼的问题,就是大事务问题。

6.8K34

聊聊spring事务失效的12种场景,太坑了

由此可见,一个类中的方法直接内部调用,会导致事务失效。 那么问题来了,如果有些场景,确实想在同一个类的某个方法中,调用它自己的另外一个方法,该怎么?...其实spring ioc内部的三级缓存保证了,不会出现循环依赖问题。但有些坑,如果你想进一步了解循环依赖问题,可以看看我之前文章《spring是如何解决循环依赖的?》。...add中,调用了事务方法doOtherThing,但是事务方法doOtherThing是另外一个线程中调用的。...因为doOtherThing方法出现了异常,没有手动捕获,会继续往上抛,到外层add方法的代理方法中捕获了异常。所以,这种情况是直接回滚了整个事务,不只回滚单个保存点。 怎么才能只回滚保存点?...这样就能保证,如果内部嵌套事务中出现异常,只回滚内部事务,而不影响外部事务。 三 其他 1 大事务问题 使用spring事务,有个让人非常头疼的问题,就是大事务问题。

36240

聊聊spring事务失效的12种场景,太坑了

由此可见,一个类中的方法直接内部调用,会导致事务失效。 那么问题来了,如果有些场景,确实想在同一个类的某个方法中,调用它自己的另外一个方法,该怎么?...其实spring ioc内部的三级缓存保证了,不会出现循环依赖问题。但有些坑,如果你想进一步了解循环依赖问题,可以看看我之前文章《spring是如何解决循环依赖的?》。...add中,调用了事务方法doOtherThing,但是事务方法doOtherThing是另外一个线程中调用的。...因为doOtherThing方法出现了异常,没有手动捕获,会继续往上抛,到外层add方法的代理方法中捕获了异常。所以,这种情况是直接回滚了整个事务,不只回滚单个保存点。 怎么才能只回滚保存点?...这样就能保证,如果内部嵌套事务中出现异常,只回滚内部事务,而不影响外部事务。 三 其他 1 大事务问题 使用spring事务,有个让人非常头疼的问题,就是大事务问题。

32330

聊聊Spring事务失效的12种场景,太坑了!

由此可见,一个类中的方法直接内部调用,会导致事务失效。 那么问题来了,如果有些场景,确实想在同一个类的某个方法中,调用它自己的另外一个方法,该怎么?...其实spring ioc内部的三级缓存保证了,不会出现循环依赖问题。但有些坑,如果你想进一步了解循环依赖问题,可以看看我之前文章《spring是如何解决循环依赖的?》。...add中,调用了事务方法doOtherThing,但是事务方法doOtherThing是另外一个线程中调用的。...因为doOtherThing方法出现了异常,没有手动捕获,会继续往上抛,到外层add方法的代理方法中捕获了异常。所以,这种情况是直接回滚了整个事务,不只回滚单个保存点。 怎么才能只回滚保存点?...这样就能保证,如果内部嵌套事务中出现异常,只回滚内部事务,而不影响外部事务。 三 其他 1 大事务问题 使用spring事务,有个让人非常头疼的问题,就是大事务问题。

38420

@Transactional 注解的12种失效场景,这坑踩个遍

由此可见,一个类中的方法直接内部调用,会导致事务失效。 那么问题来了,如果有些场景,确实想在同一个类的某个方法中,调用它自己的另外一个方法,该怎么?...其实spring ioc内部的三级缓存保证了,不会出现循环依赖问题。但有些坑,如果你想进一步了解循环依赖问题,可以看看我之前文章《spring是如何解决循环依赖的?》。...add中,调用了事务方法doOtherThing,但是事务方法doOtherThing是另外一个线程中调用的。...因为doOtherThing方法出现了异常,没有手动捕获,会继续往上抛,到外层add方法的代理方法中捕获了异常。所以,这种情况是直接回滚了整个事务,不只回滚单个保存点。 怎么才能只回滚保存点?...这样就能保证,如果内部嵌套事务中出现异常,只回滚内部事务,而不影响外部事务。 三 其他 1 大事务问题 使用spring事务,有个让人非常头疼的问题,就是大事务问题。

2.7K44

如何将 @Transactional 事务注解运用到炉火纯青?

哈哈~ ---- 第一点要注意的就是@Transactional注解的方法中,再调用本类中的其他方法method2,那么method2方法上的@Transactional注解是不!会!生!效!的!...那么继续调用本类中其他方法是怎样,如下图: 可见目标对象内部的自我调用,也就是通过this.指向的目标对象将不会执行方法的增强。...service层,加了注解也一样不起作用吧,这个懒了,没有测试,其一是因为没有人会这么开发吧,其二是就认为是不起作用的,哈哈 下面来解决一下第一点的问题,如何在方法调用本类中其他方法。...那么有人可能会有疑问了,方法1和方法2上都加@Transactional注解?答案是结果和上面是一致的。...如果想要方法1和方法2均单独保持事务一致性怎么,刚说过了,如果不是用代理调用@Transactional注解是不生效的,所以一定要使用代理调用实现,然后让方法1和方法2分别单独开启新的事务,便OK啦

24420

@Transactional千万不要这样用!!踩坑了你都可能发现不了!!!

下图是调用@Transactional注解的方法Spring内部的时序图。...了解了@Transactional的原理之后,我们回头看看之前的问题,会不会是使用方法不对导致的? 3....拨云见日 问题代码1解析 下面的代码中,我们一个类里面调用了@Transactional修饰的方法,其实这样调用的话并没有用到Spring AOP生成的代理对象。...在这个例子里面, 调用doWork一切正常,事务也会生效;但是调用doSomeCheck,从之前的分析可以看到,由于方法不是public,此时事务管理器不会起作用,直接导致所有的autowired未完成注入...( 也就是说如果A方法和B方法都添加了注解,默认传播模式下,A方法内部调用B方法,会把两个方法的事务合并为一个事务 ) Propagation.SUPPORTS:如果当前存在事务,则加入该事务;

55220

Spring事务失效的12种场景

3.方法内部调用 有时候我们需要在某个Service类的某个方法中,调用另外一个事务方法,比如: @Service public class UserService { @Autowired...由此可见,一个类中的方法直接内部调用,会导致事务失效。 那么问题来了,如果有些场景,确实想在同一个类的某个方法中,调用它自己的另外一个方法,该怎么?...add中,调用了事务方法doOtherThing,但是事务方法doOtherThing是另外一个线程中调用的。...因为doOtherThing方法出现了异常,没有手动捕获,会继续往上抛,到外层add方法的代理方法中捕获了异常。所以,这种情况是直接回滚了整个事务,不只回滚单个保存点。 怎么才能只回滚保存点?...这样就能保证,如果内部嵌套事务中出现异常,只回滚内部事务,而不影响外部事务。 三 其他 1 大事务问题 使用spring事务,有个让人非常头疼的问题,就是大事务问题。

41220

java事务回滚案例_java事务控制

疑问,确实像往常一样service上添加了注解 @Transactional,为什么查询数据库还是发现有数据不一致的情况,想想肯定是事务没起作用,出现异常的时候数据没有回滚。...Service类内部方法调用 大概就是 Service 中有一个方法 A,会内部调用方法 B, 方法 A 没有事务管理,方法 B 采用了声明式事务,通过方法上声明 Transactional 的注解来做事务管理...对于加了@Transactional注解的方法来说,调用代理类的方法,会先通过拦截器TransactionInterceptor开启事务,然后调用目标类的方法,最后调用结束后,TransactionInterceptor...代码中虽然捕获了异常,但是同时也抛出了异常,为什么事务未回滚?猜测是异常类型不对,于是开始查询原因,翻看了Spring的官方文档,找到了答案。下面是翻译自Spring官网。...解决办法是,注解@Transactional中添加 rollbackFor={BizException.class}。

1.6K10
领券