Spring service本类中方法互相调用事物失效问题
简介
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代码地址
Spring service本类中方法互相调用事物失效问题的更多相关文章
- Spring service本类中方法调用另一个方法事务不生效问题(转载)
前些日子一朋友在需要在目标对象中进行自我调用,且需要实施相应的事务定义,且网上的一种通过BeanPostProcessor的解决方案是存在问题的.因此专门写此篇帖子分析why. 1.预备知识 aop概 ...
- @Transactional-同一个类中方法自调,调用方法事物失效
问题分析 一个类中的方法调用另一个事物传播性为创建事物的方法,调用的方法事物失效? SpringAOP 代理的Service对象调用了其方法,这个方法再去调用这个Service中的其他方法是没有使用A ...
- android开发中关于继承activity类中方法的调用
android开发中关于继承activity类中的函数,不能在其他类中调用其方法. MainActivity.java package com.example.testmain; import and ...
- C#中方法的调用
C#中方法的调用 1.同一个类中方法的调用: 静态方法可以直接调用静态方法 静态方法不能直接调用非静态方法,静态方法先生成. 非静态方法可以直接调用静态方法 如果静态方法要调用非静态的方法,必须使用实 ...
- 相同类中方法间调用时日志Aop失效处理
本篇分享的内容是在相同类中方法间调用时Aop失效处理方案,该问题我看有很多文章描述了,不过大多是从事务角度分享的,本篇打算从日志aop方面分享(当然都是aop,失效和处理方案都是一样),以下都是基于s ...
- object C—类中函数的调用
Object C-类中函数的调用 创建,三个类.然后,在代码中调用相同名字的函数.观察他们的调用次序. @interface test : NSObject - (void)print; @end @ ...
- Java学习笔记(七)——获取类中方法的信息,java的LinkedList
[前面的话] 在实际项目中学习知识总是最快和最有效的,既能够较好的掌握知识,又能够做出点东西,还是简单的知识总结,最近一直在总结笔记,写的东西还是比较水,希望慢慢可以写出一些干货. 学习过程中的小知识 ...
- JAVA中方法的调用主要有以下几种
JAVA中方法的调用主要有以下几种: 1.非静态方法 非静态方法就是没有 static 修饰的方法,对于非静态方法的调用,是通过对 象来调用的,表现形式如下. 对象名.方法() eg: public ...
- C#实现调用Java类中方法
基本思路: 用C#实现调用Java编写的类中的方法:重点是将Java编写的程序打包成Jar,然后使用开源工具IKVM将其转化成DLL控件,在.NET环境下调用. 分为以下步骤: 1.下载JDK6(注: ...
随机推荐
- Python基础入门(8)- Python模块和包
1.包与模块的定义与导入 1.1.什么是python的包与模块 包就是文件夹,包中还可以有包,也就是子文件夹 一个个python文件模块 1.2.包的身份证 __init__.py是每一个python ...
- Java Web程序设计笔记 • 【第2章 JSP基础】
全部章节 >>>> 本章目录 2.1 JSP 简介 2.1.1 JSP 概述 2.1.2 开发第一个 JSP 页面 2.1.3 JSP 处理流程 2.1.4 实践练习 2. ...
- Java基础(八)——IO流3_对象流
一.对象流 1.序列化与反序列化 序列化:将内存中的Java对象保存到磁盘中或通过网络传输出去. 反序列化:将磁盘文件中的对象还原为内存中的一个Java对象. 用途: (1)将对象保存到物理硬盘:比如 ...
- pod存在,但是deployment和statefulset不存在
pod存在,但是deployment和statefulset不存在 这样的话,可以看一下是不是ReplicaSet, kubectl get ReplicaSet -n iot
- C# 使用阿里云发送短信
最近有个项目,短信服务使用的是阿里云的,由于时间问题,没有手动去构造sign去发送,而是直接使用阿里云的SDK发送,所以这里算是做个笔记,或许以后还能用得到 首先,我们需要安装阿里云的SDK,推荐使用 ...
- 初识python: 异常处理
异常处理基本语法: try: pass except Exception,ex: pass 常用异常种类: AttributeError 试图访问一个对象,没有的属性.比如foo.x,但是foo没有属 ...
- Shell统计每个单词出现的个数
题目链接 题目描述 写一个 bash脚本以统计一个文本文件 nowcoder.txt 中每个单词出现的个数. 为了简单起见,你可以假设: nowcoder.txt只包括小写字母和空格. 每个单词只由小 ...
- css 垂直居中技巧
CSS垂直居中技巧,我只会23个,你会几个?自古以来(是有多?~),网页CSS的垂直居中需求始终没有停过,而其困难度也始终没有让人轻松过,经过了每位开发先烈的研究后,据说CSS的垂直居中技巧已达到近十 ...
- Spring Security 接口认证鉴权入门实践指南
目录 前言 SpringBoot 示例 SpringBoot pom.xml SpringBoot application.yml SpringBoot IndexController SpringB ...
- MySQL提权之udf提权(无webshell的情况)
0x00 介绍 本篇我们来讲无webshell时利用udf进行提权 0x01 前提 1. 必须是root权限(主要是得创建和抛弃自定义函数) 2. secure_file_priv=(未写路径) 3. ...