简介

Spring事物利用的是AOP,动态代理采用CGLIB代理(默认,也可以用Proxy代理,但是Proxy代理效率低于CGLIB代理)。故只要弄懂Spring的AOP实现,就知道为什么service本类中方法互相调用会导致事物失效。

失效案例

service层代码

 public void  moneyTestOne(){
//1.查询病人基本信息
List<TBICXX> tbicxx = basisDao.getTBICXX();
//2.根据CMZH更新TBMZFYHZ
Integer TBMZFYHZCount = tbmzfyhzDao.updateByCMZH("王五", "1903003643");
log.info("更新TBMZFYHZ影响行数{}",TBMZFYHZCount);
this.moneyTestTwo(); } @Transactional(rollbackFor = Exception.class,propagation=Propagation.REQUIRED)
public void moneyTestTwo(){
//3.根据CMZH更新TBMZFYMXGH
Integer integer = tbmzfymxghDao.updateByCMZH("王五", "2107000224");
log.info("更新TBMZFYMXGH影响行数{}",integer);
int i=2/0;
}

Test层代码

/**
* 测试其AOP事物(CGLIB代理):
* 如moneyTestOne不添加事物,则moneyTestTwo事物及其一切传播行为将失效,这是由于spring的AOP的Cglib代理造成
* 同理: moneyTestOne添加事物,moneyTestTwo事物及其一切传播行为也将失效,moneyTestTwo运行在moneyTestOne事物中。
* $$EnhancerBySpringCGLIB$$2364c0b7 代理
**/
@Test
public void testTransationalPropagation(){
log.info("测试开始,代理类{}",springTransactionSqlserverServiceImpl.getClass());
springTransactionSqlserverServiceImpl.moneyTestOne();
}

运行前



运行后



结论

moneyTestTwo方法事物并不生效,要想事物生效,只需要在moneyTestOne方法上加上事物注解(此方法同理会导致moneyTestTwo方法传播行为失效),

失效分析

Spring通过AopProxy接口,抽象了这两种实现,实现了一致的AOP方式:



现在看来,这种抽象同样带了一个缺陷,那就是抹杀了Cglib能够直接创建普通类的增强子类的能力。下图显示了Spring的AOP代理类的实际调用过程:

解决办法

事物声明避免在一个类中互相调用,即moneyTestOne和moneyTestTwo要么都使用事物,要么直接分成两个类。

Gitee代码地址

https://gitee.com/zhuayng/foundation-study/tree/develop/SpringBootDemo/src/main/java/com/yxkj/springbootdemo/service/impl

Spring service本类中方法互相调用事物失效问题的更多相关文章

  1. Spring service本类中方法调用另一个方法事务不生效问题(转载)

    前些日子一朋友在需要在目标对象中进行自我调用,且需要实施相应的事务定义,且网上的一种通过BeanPostProcessor的解决方案是存在问题的.因此专门写此篇帖子分析why. 1.预备知识 aop概 ...

  2. @Transactional-同一个类中方法自调,调用方法事物失效

    问题分析 一个类中的方法调用另一个事物传播性为创建事物的方法,调用的方法事物失效? SpringAOP 代理的Service对象调用了其方法,这个方法再去调用这个Service中的其他方法是没有使用A ...

  3. android开发中关于继承activity类中方法的调用

    android开发中关于继承activity类中的函数,不能在其他类中调用其方法. MainActivity.java package com.example.testmain; import and ...

  4. C#中方法的调用

    C#中方法的调用 1.同一个类中方法的调用: 静态方法可以直接调用静态方法 静态方法不能直接调用非静态方法,静态方法先生成. 非静态方法可以直接调用静态方法 如果静态方法要调用非静态的方法,必须使用实 ...

  5. 相同类中方法间调用时日志Aop失效处理

    本篇分享的内容是在相同类中方法间调用时Aop失效处理方案,该问题我看有很多文章描述了,不过大多是从事务角度分享的,本篇打算从日志aop方面分享(当然都是aop,失效和处理方案都是一样),以下都是基于s ...

  6. object C—类中函数的调用

    Object C-类中函数的调用 创建,三个类.然后,在代码中调用相同名字的函数.观察他们的调用次序. @interface test : NSObject - (void)print; @end @ ...

  7. Java学习笔记(七)——获取类中方法的信息,java的LinkedList

    [前面的话] 在实际项目中学习知识总是最快和最有效的,既能够较好的掌握知识,又能够做出点东西,还是简单的知识总结,最近一直在总结笔记,写的东西还是比较水,希望慢慢可以写出一些干货. 学习过程中的小知识 ...

  8. JAVA中方法的调用主要有以下几种

    JAVA中方法的调用主要有以下几种: 1.非静态方法 非静态方法就是没有 static 修饰的方法,对于非静态方法的调用,是通过对 象来调用的,表现形式如下. 对象名.方法() eg: public ...

  9. C#实现调用Java类中方法

    基本思路: 用C#实现调用Java编写的类中的方法:重点是将Java编写的程序打包成Jar,然后使用开源工具IKVM将其转化成DLL控件,在.NET环境下调用. 分为以下步骤: 1.下载JDK6(注: ...

随机推荐

  1. 【python】PyQt5 QAction 添加点击事件

    def test(): #your function ui.yourQActionName.triggered.connect(lambda:test()) #添加lambda: 就不报错了

  2. 知识增强的预训练语言模型系列之ERNIE:如何为预训练语言模型注入知识

    NLP论文解读 |杨健 论文标题: ERNIE:Enhanced Language Representation with Informative Entities 收录会议:ACL 论文链接: ht ...

  3. Linux磁盘实用指令

    磁盘情况查询 df/du 查询磁盘整体占用情况 df 指令:df -h 查询目录磁盘占用情况 du 基本语法 指令:du [选项] 指定目录 常用选项 指定目录不填则默认当前目录 选项 功能 -s 指 ...

  4. 初识python 之 爬虫:使用正则表达式爬取“糗事百科 - 文字版”网页数据

    初识python 之 爬虫:使用正则表达式爬取"古诗文"网页数据 的兄弟篇. 详细代码如下: #!/user/bin env python # author:Simple-Sir ...

  5. python的赋值、浅拷贝和深拷贝

    """ 一.赋值在python中就是简单的对象引用 """ list_a = ["aaa", "bbb&quo ...

  6. java mapreduce二次排序

    原文链接: https://www.toutiao.com/i6765808056191156748/ 目的: 二次排序就是有下面的数据 a 3 a 1 a 100 c 1 b 2 如果只按照abc排 ...

  7. JSP页面实际上就是Servlet

    注:图片如果损坏,点击文章链接:https://www.toutiao.com/i6513069824690618883/ 前面一直提到了Servlet的内容,也是我们平时理解的后台,这次说一下前台的 ...

  8. console.log(a)和console.log(window.a)的区别?

    console.log(window.l); //undefined console.log(l); //Uncaught ReferenceError: l is not defined js对于未 ...

  9. SYCOJ#111、吉祥物

    题目-吉祥物 (shiyancang.cn) 1 #include<bits/stdc++.h> 2 using namespace std; 3 int n,x; 4 int pos(i ...

  10. CodeForces 519B A and B and Compilation Errors (超水题)

    这道题是超级水的,在博客上看有的人把这道题写的很麻烦. 用 Python 的话是超级的好写,这里就奉上 C/C++ 的AC. 代码如下: #include <cstdio> #includ ...