在使用spring事务的时候,如果使用不当,有可能会出现事务失效的问题,接下来,我基于自己的见解和学习,分享下我的看法

对于非public方法这种场景,我觉得这是最好理解的一种场景,@Transactional注解加在非public修饰的方法上,就不会生效,这个是没问题的,接下来,我分析下为什么非public方法会失效,其实在这篇博客中已经介绍了一部分:spring事务源码-代理对象生成过程解析

spring事务也是通过动态代理来实现的,spring事务也是借鉴了AOP的思想,在对一个bean进行初始化的过程中,在执行到第八个后置处理器方法,org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#postProcessAfterInitialization
这里是怎么调用过去的,就不说了,在前面的笔记中有记录过,在这个方法中,会判断当前bean是否要生成代理对象,在判断的过程中,就和这里要说的非public判断有关系,在判断是否要生成代理对象的时候,会调用到这个方法org.springframework.transaction.interceptor.AbstractFallbackTransactionAttributeSource#computeTransactionAttribute

// Don't allow no-public methods as required.
if (allowPublicMethodsOnly() && !Modifier.isPublic(method.getModifiers())) {return null;
}

可以看到,在方法刚进来的时候,就会有这么一个判断,第二个判断就简单了,就是判断当前method是否是public的,对于第一个判断

org.springframework.transaction.annotation.AnnotationTransactionAttributeSource#allowPublicMethodsOnly/*** By default, only public methods can be made transactional.*/
@Override
protected boolean allowPublicMethodsOnly() {return this.publicMethodsOnly;
}

其实就是返回了publicMethodsOnly这个变量,那既然是返回的这个变量,就看下在哪里对这个值进行了赋值,在AnnotationTransactionAttributeSource这个类中,进行全局搜索,会发现,这个变量只有在构造函数中赋值了,那就简单了,看下在哪里有调用构造方法就可以了
这个构造方法中,进行了赋值,其他的构造方法,默认publicMethodsOnly = true,所以我们要看下这个构造函数是在哪里被调用的

public AnnotationTransactionAttributeSource(boolean publicMethodsOnly) {this.publicMethodsOnly = publicMethodsOnly;if (jta12Present || ejb3Present) {this.annotationParsers = new LinkedHashSet<>(4);this.annotationParsers.add(new SpringTransactionAnnotationParser());if (jta12Present) {this.annotationParsers.add(new JtaTransactionAnnotationParser());}if (ejb3Present) {this.annotationParsers.add(new Ejb3TransactionAnnotationParser());}}else {this.annotationParsers = Collections.singleton(new SpringTransactionAnnotationParser());}
}

会发现,这个构造函数是在本类中的另外一个构造方法调用

public AnnotationTransactionAttributeSource() {this(true);}

那到这里,我们知道,spring的@EnableTransactionManager注解会注入三个bean,

看到这个截图,其实我觉得基本上就明了了
首先在注入这个bean的时候,调用的是无参构造函数,在无参构造函数中,指定了publicMethodsOnly为true,所以,如果我们不做任何改造的情况下,我们在使用事务的时候,是只允许public方法进行代理对象生成的
其实在没有看源码之前,我一直以为是在生成代理对象的时候,判断了是否是public方法,现在看来,其实不是的,jdk或者cglib都可以为非public方法生成代理对象,并不是我不给你生成,而是spring事务自己在调用动态代理之前,已经对非public方法过滤了,所以这是非public方法,事务不生效的原因
反而言之,如果我们修改了spring的源码,把默认的

public AnnotationTransactionAttributeSource() {this(true);}
修改为
public AnnotationTransactionAttributeSource() {this(false);}

那默认就可以为非public方法生成代理对象了

spring事务失效一:非public方法相关推荐

  1. Spring事务失效 -方法内部调用

    首先感谢网友的文章 Spring事务失效的2种情况 JDK动态代理给Spring事务埋下的坑 前提知识: 两个前提 1 注解使用 spring容器的事务管理注解 @org.springframewor ...

  2. Spring 事务失效?看这篇文章就够了!

    欢迎关注方志朋的博客,回复"666"获面试宝典 用 Spring 的 @Transactional 注解控制事务有哪些不生效的场景? 不知道小伙伴们有没有这样的经历,在自己开心的编 ...

  3. 详细整理Spring事务失效的具体场景及解决方案

    实际项目开发中,如果涉及到多张表操作时,为了保证业务数据的一致性,大家一般都会采用事务机制:好多小伙伴可能只是简单了解一下,遇到事务失效的情况,便会无从下手,溪源此篇文章给大家整理了一下常见Sprin ...

  4. Spring 事务失效的 8 大场景,看看你都遇到过几个?

    点击关注公众号,实用技术文章及时了解 来源:blog.csdn.net/Yang_yangyang/ article/details/114359881 用 Spring 的 @Transaction ...

  5. 面试官:Spring事务失效的场景有哪些?如何解决?

     作者:溪~源 blog.csdn.net/xuan_lu/article/details/107797505 实际项目开发中,如果涉及到多张表操作时,为了保证业务数据的一致性,大家一般都会采用事务机 ...

  6. 你否有遇到Spring事务失效,花费太多时间找bug

    作者:溪~源 来源:blog.csdn.net/xuan_lu/article/details/107797505 实际项目开发中,如果涉及到多张表操作时,为了保证业务数据的一致性,大家一般都会采用事 ...

  7. spring事务失效了? @Transactional不管用了 ?看看这些@Transation的坑

    spring事务失效了? @Transactional不管用了 ?看看这些@Transactional的坑 文章目录 spring事务失效了? @Transactional不管用了 ?看看这些@Tra ...

  8. 8个Spring事务失效的场景,你碰到过几种?

    前言 作为Java开发工程师,相信大家对Spring种事务的使用并不陌生.但是你可能只是停留在基础的使用层面上,在遇到一些比较特殊的场景,事务可能没有生效,直接在生产上暴露了,这可能就会导致比较严重的 ...

  9. 详解spring事务失效和回滚失败的场景

    详解spring事务失效和回滚失败的场景 详解spring事务失效和回滚失败的场景 前言 一 .事务不生效 1.访问权限问题 2. 方法用final修饰 3.方法的内部调用 3.1 新加一个Servi ...

  10. try-catch捕获异常信息后Spring事务失效处理方法

    一.首先在Spring Boot项目中,手动添加异常方法进行测试 @Transactional(rollbackFor=Exception.class) //表示此方法有异常时触发Spring事务 @ ...

最新文章

  1. 机器学习与深度学习常见面试问题与答案
  2. 学计算机专业的毕业证,对于计算机专业的同学来说,学历真的那么重要吗?
  3. 【ruoyi若依】Caused by: java.lang.NoClassDefFoundError: com/sun/jna/platform/win32/VersionHelpers
  4. python中空格属于字符吗_举例说明python中空格是属于字符
  5. MATLAB2016下载地址,包含安装教程
  6. 【论文】Awesome Relation Extraction Paper(关系抽取)(PART IV)
  7. 【OpenGL】OpenGL安装glew扩展库
  8. SpringApplication#run⽅法第5步,打印banner(四)
  9. c语言源码转流程图,C语言算法第5章源代码以及流程图.doc
  10. 网络变压器 网络变压器设计线路分类及其设计目的和侧重点
  11. 会议安排(经典贪心算法例题)
  12. C#:TopK:1万个数取前最大的100,堆排序
  13. java心形动画效果_java swing实现动态心形图案的代码下载
  14. 基因组测序为什么没完没了?
  15. 电能减去热能计算机械能,力与运动机械能热能计算题
  16. 第六章 Java API
  17. 年度绩效考核演示PPT模板
  18. Git提交指定的文件
  19. 三角函数之角度与弧度
  20. 成功解决:curl: (7) Failed connect to github-production-release-asset-2e65be.s3.amazonaws.com:443; 拒绝连接

热门文章

  1. 翻译: 4.4. 模型选择Model Selection、欠拟合Underfitting和过拟合Overfitting pytorch
  2. 容器技术Docker K8s 25 容器服务ACK基础与进阶-监控管理
  3. 容器技术Docker K8s 8 容器服务ACK Pro版集群
  4. iOS 13问题记录
  5. PyTorch搭建LeNet-5模型(在MNIST数据集上准确率接近100%)
  6. NumPy库---数组的基本操作
  7. Command python setup.py egg_info failed with error code 1 in
  8. Dialogue and Conversational Agents
  9. MapReduce如何使用多路输出
  10. 【POJ 2482】【扫描线问题】Stars in Your Window【包星星问题】