简介

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. 「ARC096C」Everything on It

    Solution 容斥,钦定 \(i\) 个数 \(\leq 1\) 次. \[Ans=\sum_{i=0}^n (-1)^i\binom{n}{i}F(i) \] 其中 \(F(i)\) 表示有 \ ...

  2. [炼丹术]使用Pytorch搭建模型的步骤及教程

    使用Pytorch搭建模型的步骤及教程 我们知道,模型有一个特定的生命周期,了解这个为数据集建模和理解 PyTorch API 提供了指导方向.我们可以根据生命周期的每一个步骤进行设计和优化,同时更加 ...

  3. Unity——卡通渲染实现

    效果展示: 原模型: 一.简单分析 卡通渲染又叫非真实渲染(None-Physical Rendering-NPR),一般日漫里的卡通风格有几个特点: 1.人物有描边 2.有明显的阴影分界线,没有太平 ...

  4. linux脚本重启java服务

    !/bin/bashpid=$(ps -ef | grep zwdatatransfer-1.0.0.jar | grep -v 'grep' | awk '{print $2}')kill -9 $ ...

  5. Zookeeper单机安装(开启kerberos)

    安装规划 zookeeper安装到zdh41上面,单机模式 10.43.159.41 zdh41 ZDH.COM 安装用户 zookeeper/zdh1234 useradd -g hadoop -s ...

  6. 【】Hadoop生态圈介绍

    Technorati 标记: hadoop,生态圈,ecosystem,yarn,spark,入门 1. hadoop 生态概况 Hadoop是一个由Apache基金会所开发的分布式系统基础架构. 用 ...

  7. 痞子衡嵌入式:在IAR开发环境下将整个源文件代码重定向到任意RAM中的方法

    大家好,我是痞子衡,是正经搞技术的痞子.今天痞子衡给大家分享的是在IAR开发环境下将整个源文件代码重定向到任意RAM中的方法. 痞子衡旧文 <在IAR下将关键函数重定向到RAM中执行的方法> ...

  8. [BJDCTF2020]EzPHP-POP链

    那次某信内部比赛中有道pop链问题的题目,我当时没有做出来,所以在此总结一下,本次以buu上复现的[MRCTF2020]Ezpop为例. 题目 1 Welcome to index.php 2 < ...

  9. Python 为什么不设计 do-while 循环结构?

    在某些编程语言中,例如 C/C++.C#.PHP.Java.JavaScript 等等,do-while 是一种基本的循环结构. 它的核心语义是:先执行一遍循环体代码,然后执行一遍条件语句,若条件语句 ...

  10. Pod:Kubernetes最小执行单元

    Pod基本概念理解 Pod是什么 Pod 是 Kubernetes 应用程序的基本执行单元,它是 Kubernetes 对象模型中创建或部署的最小和最简单的单元. 一个Pod可以包括一个或者多个容器. ...