问题:

在Spring管理的项目中,方法A使用了Transactional注解,试图实现事务性。但当同一个class中的方法B调用方法A时,会发现方法A中的异常不再导致回滚,也即事务失效了。

当这个方法被同一个类调用的时候,spring无法将这个方法加到事务管理中。

我们来看一下生效时候和不生效时候调用堆栈日志的对比。

 
 

通过对比两个调用堆栈可以看出,spring的@Transactional事务生效的一个前提是进行方法调用前经过拦截器TransactionInterceptor,也就是说只有通过TransactionInterceptor拦截器的方法才会被加入到spring事务管理中,查看spring源码可以看到,在AdvisedSupport.getInterceptorsAndDynamicInterceptionAdvice方法中会从调用方法中获取@Transactional注解,如果有该注解,则启用事务,否则不启用。

 
 

这个方法是通过spring的AOP类CglibAopProxy的内部类DynamicAdvisedInterceptor调用的,而DynamicAdvisedInterceptor继承了MethodInterceptor,用于拦截方法调用,并从中获取调用链。

如果是在同一个类中的方法调用,则不会被方法拦截器拦截到,因此事务不会起作用,必须将方法放入另一个类,并且该类通过spring注入。

原因:

Transactional是Spring提供的事务管理注解。

重点在于,Spring采用动态代理(AOP)实现对bean的管理和切片,它为我们的每个class生成一个代理对象。只有在代理对象之间进行调用时,可以触发切面逻辑。

而在同一个class中,方法B调用方法A,调用的是原对象的方法,而不通过代理对象。所以Spring无法切到这次调用,也就无法通过注解保证事务性了。

也就是说,在同一个类中的方法调用,则不会被方法拦截器拦截到,因此事务不会起作用。

解决方法1:

将事务方法放到另一个类中(或者单独开启一层,取名“事务层”)进行调用,即符合了在对象之间调用的条件。

解决方法2:

获取本对象的代理对象,再进行调用。具体操作如:

1) Spring-content.xml上下文中,增加配置:<aop:aspectj-autoproxy expose-proxy="true"/>

2) 在xxxServiceImpl中,用(xxxService)(AopContext.currentProxy()),获取到xxxService的代理类,再调用事务方法,强行经过代理类,激活事务切面。

解决方法3:

很多时候,方法内调用又希望激活事务,是由于同一个方法既有DAO操作又有I/O等耗时操作,不想让耗时的I/O造成事务的太长耗时(比如新增商品同时需要写入库存)。此时,可以将I/O做成异步操作(如加入线程池),而加入线程池的操作即便加入事务也不会导致事务太长,问题可以迎刃而解。
解决方法4:

用@Autowired 注入自己 然后在用注入的bean调用自己的方法也可以

参考:
https://blog.csdn.net/ligeforrent/article/details/79996797

https://www.jianshu.com/p/2e4e1007edf2

分析spring事务@Transactional注解在同一个类中的方法之间调用不生效的原因及解决方案的更多相关文章

  1. Spring @Cacheable注解 && 事务@Transactional 在同一个类中的方法调用不生效

    @Cacheable 注解在对象内部调用不会生效 代码示例:ProductServiceImpl.java public List<ProductInfoVO> getProductLis ...

  2. Spring同一个类中的注解方法调用AOP失效问题总结

    public interface XxxService { // a -> b void a(); void b(); } @Slf4j public class XxxServiceImpl ...

  3. Spring事务:调用同一个类中的方法

    问题: 如果同一个类中有方法:methodA(); methodB().methodA()没有开启事务,methodB()开启了事务 且methodA()会调用methodB(). 那么,method ...

  4. 梳理:python—同一个类中的方法调用

    为什么突然在此提到这个梳理问题呢? 因为在自己实践综合练习学过的知识时,突然觉得有些知识点的运用总是不成功,于是翻过课本进行回顾,总是觉得是对的,可是当再进一步思考“既然是对的,为什么在程序中总是不成 ...

  5. java中方法内可以调用同一个类中的方法

    在同一个类中,java的普通方法的相互调用,可以使用this+点号+方法名,也可省略this+点号,java编 译器会自动补上.

  6. C#同一项目中不同文件或类中的方法进行调用

    有两种方法,一是将被调用的类设置成静态类Static,这样就可以直接点出来了,二是将被调用的方法所在类设置成public,这几必须在调用类中先将被调用的类进行实体化,new()出来,再点出来. 一. ...

  7. spring 事务处理中,同一个类中:A方法(无事务)调B方法(有事务),事务不生效问题

    public class MyEntry implements IBaseService{ public String A(String jsonStr) throws Exception{ User ...

  8. java同一个类中,构造器如何调用另一个重载的构造器?

    构造器里面调用其它构造器,格式方法如下:1.使用this调用另一个重载构造器,只能在构造器中使用:2.必须写在构造器执行体的第一行语句: 示例如下: import static java.lang.S ...

  9. Transaction 在同一个类中不生效

    参考:https://blog.csdn.net/qq_30336433/article/details/83338835 最近在开发项目中踩到一个坑,以此记录下来.以备后来人借鉴 1.相信使用spr ...

随机推荐

  1. k8s的监控

    监控 1.资源指标和资源监控 一个集群系统管理离不开监控,同样的Kubernetes也需要根据数据指标来采集相关数据,从而完成对集群系统的监控状况进行监测.这些指标总体上分为两个组成:监控集群本身和监 ...

  2. 《Hello--world团队》第三次作业:团队项目的原型设计

    项目 内容 这个作业属于哪个课程 2016级计算机科学与工程学院软件工程(西北师范大学) 这个作业的要求在哪里 实验七 团队作业3:团队项目原型设计与开发 团队名称 <hello--world团 ...

  3. Robot Framework--连接Mysql数据库

    1.安装Database-Library 输入命令:pip install robotframework_databaselibrary 2.添加Database的Library 3.实例 *** T ...

  4. Accounts Merge

    Description Given a list accounts, each element accounts[i] is a list of strings, where the first el ...

  5. windows nginx 搭建文件服务器(通俗易懂)

    在一些项目里面,有时候需要访问图片的时候.相信很多人都是的直接把文件放到项目里面的: 今天在这里给大家介绍的是利用nginx 搭建图片服务器,直接访问磁盘上的图片. 方法一(使用root关键字): l ...

  6. 十四.自定义yum仓库、源码编译安装

    pc7:192.168.4.7 1.自定义yum仓库1.1 源码仓库下:/root/tools/other]# createrepo .]# ls ntfs-3g-2014.2.15-6.el6.x8 ...

  7. 如何利用Wireshark解密SSL和TLS流量

    如何利用Wireshark解密SSL和TLS流量https://support.citrix.com/article/CTX135121 1.有server端的private key,直接在wires ...

  8. 好用的Google Chrome插件

    juejin掘金 帮助我们随时了解Github上热门的项目,保证技术思想不掉队. Momentum 专注.待办清单…… Octotree Octotree 可以让我们在 Github 上浏览代码更加方 ...

  9. Fidller抓包分析post请求

    目的:抓包是为了最近做接口测试做准备,以前没有用过这个工具,最近来学下,但是网上很多文章了,所以不一一记录,有一部分参考即可 1.如何抓取想要的web端或者手机端包,已经有很多文章谢了,推荐的参考文章 ...

  10. (转)SmartPing:一个服务器Ping值监测工具

    官网:https://docs.smartping.org/ 借鉴:https://www.moerats.com/archives/710/ 说明:之前博主发过一个雨落大神写的Ping值监测工具uP ...