spring-transaction源码分析(3)Transactional事务失效原因

news/2024/12/2 20:45:05/

问题概述

在Transactional方法中使用this方式调用另一个Transactional方法时,拦截器无法拦截到被调用方法,严重时会使事务失效。

类似以下代码:

@Transactional
public void insertBlogList(List<Blog> blogList) {for (Blog blog : blogList) {this.blogMapper.insertBlog(blog);}try {TimeUnit.SECONDS.sleep(15);} catch (InterruptedException e) {e.printStackTrace();}
}@Transactional
public void deleteBlogByCondition(BlogSearchParameter parameter) {List<Blog> blogs = this.blogMapper.selectBlogByParameter(parameter);for (Blog blog : blogs) {this.blogMapper.deleteBlog(blog.getId());}// 抛出一个RuntimeExceptionthrow new RuntimeException("deleteBlogByCondition抛出一个异常");
}@Transactional
public void insertAndDeleteBlogList2(List<Blog> blogList, BlogSearchParameter parameter) {// 插入数据this.insertBlogList(blogList);// 删除数据try {this.deleteBlogByCondition(parameter);} catch (Exception e) {System.err.printf("Err:%s%n", e.getMessage());}System.out.println("继续插入数据");// 继续插入数据this.insertBlogList(blogList);
}

正常情况下,执行到"继续插入数据"时会抛出一个"rollback only"的异常,然后事务回滚。

而现在的现象是:

  • 三个操作都不会开启事务,出现异常也不会回滚
  • "删除数据"操作会把符合条件的数据都删除掉
  • "继续插入数据"操作会再插入数据

原因分析

在EnableTransactionManagement注解mode属性的文档中:

The default is AdviceMode.PROXY. Please note that proxy mode allows for interception of calls through the proxy only. Local calls within the same class cannot get intercepted that way; an Transactional annotation on such a method within a local call will be ignored since Spring's interceptor does not even kick in for such a runtime scenario. For a more advanced mode of interception, consider switching this to AdviceMode.ASPECTJ.

大概意思是:mode属性的默认值是AdviceMode.PROXY,这种方式仅允许通过代理对来调用事务方法,同一个类的本地调用无法被事务切面拦截。如果要解决这个问题,可以使用AdviceMode.ASPECTJ模式。

其实这个问题的根本原因与spring-tx无关,而是spring-aop的实现方式造成的。

从spring-aop拦截器分析问题原因

在DynamicAdvisedInterceptor和JdkDynamicAopProxy中有一段类似的代码:

在这里插入图片描述

在这里插入图片描述

其中target就是原始的业务层Bean对象。

在后续创建ReflectiveMethodInvocation/CglibMethodInvocation时又将此target传递了进去:

// JDK
MethodInvocation invocation =new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain);
retVal = invocation.proceed();// Cglib
retVal = new CglibMethodInvocation(proxy, target, method, args, targetClass, chain, methodProxy).proceed();

proceed方法中在拦截器链最后会调用目标方法:

public Object proceed() throws Throwable {// We start with an index of -1 and increment early.if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {return invokeJoinpoint();}// 略
}protected Object invokeJoinpoint() throws Throwable {// 反射调用目标方法// 这个target就是原始Bean对象return AopUtils.invokeJoinpointUsingReflection(this.target, this.method, this.arguments);
}

所以如果在目标方法中使用this方法调用另一个需要被拦截的方法,将不会执行拦截逻辑。


http://www.ppmy.cn/news/64220.html

相关文章

MapReduce调优

MapReduce调优 MapReduce应用场景优点缺点擅长应用场景不擅长应用MapReduce优化需求与方向 文件存储格式行式存储、列式存储Sequence File优缺点Sequence File格式Sequence File 未压缩格式Sequence File 基于record压缩格式Sequence File基于block压缩格式生成Sequence File文…

虚拟环境中的 CPU 优化

近年来&#xff0c;虚拟化已成为管理计算资源的一种越来越流行的方式&#xff0c;使用户能够在一台机器上运行多个操作系统和应用程序。虽然虚拟化提供了许多好处&#xff0c;例如更好的资源利用率和更大的灵活性&#xff0c;但在优化 CPU 性能方面也可能带来挑战。 在本文中&…

@Configuration(proxyBeanMethods = false) 解析

又是美好的一天呀~ 个人博客地址&#xff1a; huanghong.top 往下看看~ Configuration(proxyBeanMethods false) 解析proxyBeanMethods分析总结 Configuration(proxyBeanMethods false) 解析 最近看一些源码的时候&#xff0c;发现很多Configuration配置类上Configuration(p…

阿里、京东等大厂年薪50w的测试都是什么水平?

各位做测试的朋友&#xff0c;但凡经历过几次面试&#xff0c;那么你一定曾被问到过以下问题&#xff1a; 1、在Linux环境下&#xff0c;怎么执行web自动化测试&#xff1f; 2、Shell如何&#xff0c;Docker熟悉吗&#xff1f; 3、全链路的压测实操过吗&#xff0c;如何推进与开…

如何使用Typeface-Helper-自定义字体

随着科技的不断发展&#xff0c;人们对于视觉效果的要求也越来越高。在设计领域中&#xff0c;字体设计是非常重要的一环&#xff0c;因为它直接影响了整个设计的风格和品质。因此&#xff0c;越来越多的设计师开始寻找能够帮助他们自定义字体的工具。在这个过程中&#xff0c;…

【JavaEE初阶】文件操作——IO

摄影分享~ 文章目录 文件文件路径&#xff08;Path&#xff09; 文件的类型Java中操作文件File概述 文件内容的读写——数据流字节流InputStream概述OutputStream 概述字符流FileInputStream 概述利用 Scanner 进行字符读取 实例练习 文件 文件&#xff1a;File这个概念&…

KingbaseES 的角色和权限管理

KingbaseES使用角色的概念管理数据库访问权限。为了方便权限管理&#xff0c;用户可以建立多个角色&#xff0c;对角色进行授权和权限回收&#xff0c;并把角色授予其他用户。 数据库初始化时&#xff0c;会创建一个超级用户的角色&#xff1a;system(默认&#xff0c;可修改)。…

洗地机怎么选?高性价比家用洗地机推荐

洗地机是一款高效、智能的清洁设备&#xff0c;可轻松去除地面污渍&#xff0c;免除了传统清洁方式的繁琐和费时。采用高科技材料和技术&#xff0c;可快速有效地将地面污物清除&#xff0c;保持环境卫生和清爽。但是面对市场上众多的洗地机品牌&#xff0c;许多家人们都不知道…