面试官:说说 Spring 中事务的嵌套 ?

Gazebo仿真环境下的强化学习实现 实际上利用Gazebo进行强化学习无非是环境获取上的不同,Gazebo的环境控制需要使用ROS服务进行控制,状态可以通过Gazebo进行获取,同时某些必要数据需要从话题中获取,最重要的是组织获取 的数据(通过话题等)与控制Gazebo的仿真步骤之间的组合。强化学习的手段与传统算法无异,强化学习方法最重要的是要确定动作空间、状态空间、奖励空间,这三个空间是work的前提。在笔者自己的环境中,将获取里程计的话题以及获取激光点的数据替换成为了自己的本机的仿真环境匹配的话题。 阅读详情

点击关注公众号:互联网架构师,后台回复 2T获取2TB学习资源!

上一篇:Alibaba开源内网高并发编程手册.pdf

Spring事务的的详细理解,事务嵌套解析,以及事务失效的场景解惑

想要了解Spring的事务嵌套,我们先了解一下Spring的七种事务传播属性各自表示的意思

  1. propagation_requierd:如果当前没有事务,就新建一个事务,如果已存在一个事务中,加入到这个事务中,这是最常见的选择。

  2. propagation_supports:支持当前事务,如果没有当前事务,就以非事务方法执行。

  3. propagation_mandatory:使用当前事务,如果没有当前事务,就抛出异常。

  4. propagation_required_new:新建事务,如果当前存在事务,把当前事务挂起。

  5. propagation_not_supported:以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。

  6. propagation_never:以非事务方式执行操作,如果当前事务存在则抛出异常。

  7. propagation_nested:如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则执行与propagation_required类似的操作

了解了这七种传播属性表示的意思,接下来在说具体的解释

详解Spring的事务传播属性以及在写代码的过程中发生嵌套并发生事务失效的场景

再说这些之前,大家先要清除一个问题,Spring的事务是怎么实现的?

Spring本身是没有事务的,只有数据库才会回有事务,而Spring的事务是借助AOP,通过动态代理的方式,在我们要操作数据库的是时候,实际是Spring通过动态代理进行功能扩展,在我们的代码操作数据库之前通过数据库客户端打开数据库事务,如果代码执行完毕没有异常信息或者是没有Spring要捕获的异常信息时,再通过数据库客户端程序提交事务,如果有异常信息或者是有Spring要捕获的异常信息,再通过数据库客户端程序回滚事务,从而达到控制数据库事务的目的。

1、Spring的事务的简单原理示意图,请看下图

e01eda708cfcda4ca3c96f46f47c128a.png

2、Spring的Transactional注解默认情况下的传播属性是什么呢,请看一下Transactional的源码:下图所示(所以在默认的情况下我们加了Transactional 就会有事务)

17ae03ce78f4784e354140412b29fffb.png

3、第1、第2两部分看明白之后,再来说一下Spring事务嵌套会发生的情况

3.1、在同一个类中发生事务嵌套的情况

007c130ec5c1de9ac713586e8a2cf181.png

答案是会回滚的,原因是什么呢?接着看下边的示意图

2c3ecc615a70bad1552bbd95c3186474.png

看上边的示意图你一定会明白了吧,原因还是因为代理的时候,直接把没有事务的方法包在了有事务的代理方法里边了自然就有事务了,这样说够明确吗?不够的话可以留言,给你解答一下

3.2 再看一种嵌套的方式

0389f70eea0f7b0f3ce62d0aa45ecbf8.png

答案:这时候调用test02,test01有异常发生时是不会回滚的

为什么呢?其实如果上边的你理解了下边就很容易理解了

29e05aa35926e6d27816304a2cb30edf.png

3.3 这些明白了 后边的就更容易明白了,再看一个例子

cbc7c4c58ac0b7818769125fdd903c7c.png

上述3.3中的例子,如果调用test02 的话,当程序发生异常,test01会不会回滚呢?

答案是会回滚的 原因和3.1中的情况类似

所以综合上边说的,在同一个类中事务嵌套的话,最终的结果应该是取决于最外层的方法事务的传播特性

4、以上是在一个相同的类中的情况,如果是不同的类中的方法嵌套调用是什么样子的呢?

4.1 我们来看下列一种情况

b8a9e34eff7cdc6f140c8ffe73514c70.png

在TestService3中调用TestService4中的没有事务的方法,会发生什么呢?TestService4中的test41方法发生异常会回滚吗?

答案 会的

为什么呢请看下图:

ba8efddf7174f06d9dbf11a5d7304df6.png

4.2 我们再来看一个情况

794080d7c0d3e5023a247e61eb04771a.png

TestService3中的方法是有事务的,TestService4中的方法是以非事务的方式运行,如果存在事务就挂起事务,那么自然就没有事物了

所以上述的情况就是,如果TestService4中的方法报出异常,则TestService3中的数据可以回滚,但是TestService4中操作的数据是不会回滚的

再有其他的情况大家根据上述的原理,然后结合传播属性的特点去套就可以了

总结4中的案例得到的结论是,如果是不同的类的事务嵌套的话,外层的方法按照外层的事务传播属性执行,内层的传播属性按照内层的传播属性的特点去运行

5、下边介绍一些目前我知道的Spring事务会失效的情况

5.1 事务方法访问修饰符不是public,导致事务失效

比如 下图中的代码

44b87c5d106ec1f977584f0c5757974b.png

其实如果是JDK的动态代理 就不允许这种情况,因为JDK动态代理需要有接口,而接口中是不能有 私有方法的,如果是CGLIB动态代理的话也是不允许的代理private方法的

5.2 如果事务方法是static、final的,同样无法通过动态代理,事务也是不会生效的。Spring的声明式事务是基于动态代理实现的,我们无法重写final修饰的方法;不管是JDK动态代理还是Cglib的动态代理,就是要通过代理的方式获取到代理的具体对象,而static方法修饰的方法是属于类对象的,不属于任何实例对象,所以static方法不能被重写也就是说static方法也不被进行动态代理。

5.3 操作的数据库表如果本身不支持事务 那么配置的Spring事务 也会失效

5.4 代码中的异常被 catch 住,而且没有异常再次抛出,也会让spring的事务失效,如下图中所示 事务就会失效

5d18fbbcd9ea3a5ca1ea3328792a2718.png

想要 避免上述的失效的话 可以 在catch 住后在catch块中再次 抛出Spring事务支持的异常,就可以了

5.5 多线程的调用导致事务的失效,例如 下边的案例 会导致 test31的事务失效

0e27e67c3f08ce23b62b51b767167893.png

解释:原因是因为 test31中操作数据要回滚,需要有异常抛出才可以回滚,但是由于线程异步运行这种写法,test31和test41分别是两个独立的事务,他们的数据库链接都可能是不同的,要想回滚则test31和test41都应该有异常抛出才可以。

但是test31所在的线程没有捕获到test41所在的子线程的异常所以没有回滚,之所以没有捕获到test41所在的线程的异常是因为test41相对test31是异步运行,可能test31已经运行完了,但是test41还没有运行完,所以在写这种代码的时候大家可以使用thread.setUncaughtExceptionHandler方法来处理线程内部的异常,也就是当thread报出异常的时候可以在这个方法中再次抛出异常这样可以触发外部事务的回滚,或者也可以采用下列的代码

@Transactional(propagation = Propagation.REQUIRED,rollbackFor = Exception.class)
public  void test31() throws ExecutionException, InterruptedException {
    Map<String,Object> map=new HashMap<>();
    map.put("id",3);
    map.put("quantity",300);
    int i = testDao.updateStock(map);

    FutureTask task=new FutureTask(new Callable() {
        @Override
        public Object call() throws Exception {
            testService4.test41();
            return "ok";
        }
    });
    Thread thread = new Thread(task);

    thread.start();
    //等待执行结果,当有异常的时候在这里就可以获取到异常传递给test31触发他的回滚
    Object ok = task.get();
    System.out.println("=============OK");
}

原文:blog.csdn.net/licigao/article/details/125314484

最后,关注公众号互联网架构师,在后台回复:2T,可以获取我整理的 Java 系列面试题和答案,非常齐全。

正文结束

推荐阅读 ↓↓↓

1.JetBrains 如何看待自己的软件在中国被频繁破解?

2.Alibaba开源内网高并发编程手册.pdf

3.程序员一般可以从什么平台接私活?

4.40岁,刚被裁,想说点啥。

5.为什么国内 996 干不过国外的 955呢?

6.中国的铁路订票系统在世界上属于什么水平?                        

7.15张图看懂瞎忙和高效的区别!

e111e5345724d3d052f38a84061cb915.gif

【通信协议】GATT 与 BLE HID 工作原理详解 详细介绍BLE HID 跟GATT工作原理与两者的交互关系 阅读详情

相关推荐

【国产MCU】-认识CH32V307及开发环境搭建

CH32V307是[沁恒](https://www.wch.cn/)推出的一款基于32位RISC-V设计的互联型微控制器,配备了硬件堆栈区、快速中断入口,在标准RISC-V基础上大大提高了中断响应速度。加入单精度浮点指令集,扩充堆栈区,具有更高的运算性能。扩展串口UART数量到8组,电机定时器到4组。提供USB2.0高速接口(480Mbps)并内置了PHY收发器,以太网MAC升级到千兆并集成了10M-PHY模块。

视觉与物联智能 2261

Spring事务嵌套详解

5.1 事务方法访问修饰符不是public,导致事务失效比如 下图中的代码其实如果是JDK的动态代理 就不允许这种情况,因为JDK动态代理需要有接口,而接口中是不能有 私有方法的,如果是CGLIB动态代理的话也是不允许的代理private方法的5.2 如果事务方法是static、final的,同样无法通过动态代理,事务也是不会生效的。Spring的声明式事务是基于动态代理实现的,我们无法重写final修饰的方法;

a984171281的博客 2540

第一章:信号链的精度之战:深入解决电流采样偏差

摘要:本文深入探讨了FOC控制中电流采样偏差问题及其解决方案。电流采样偏差主要来源于偏移误差、增益误差、非线性误差和温漂四大类,其中偏移误差对FOC性能影响最为严重。硬件方面建议采用高精度采样电阻、低失调运放和独立基准电压等设计;软件层面提出了上电自动零点校准、在线实时补偿和模型闭环补偿三种策略。最后介绍了量产自动化校准系统,通过硬件优化和软件补偿相结合,确保每台产品电流采样精度的一致性,为FOC控制奠定坚实基础。

汽车软件开发 550

面试必问的事务-2.2:事务嵌套

通过分析一些事务嵌套的场景,来深入理解spring事务传播机制。 1:简单举例分析 假设外层事务 Service A 的 Method A() 调用 内层Service B 的 Method B() PROPAGATION_REQUIRED(spring 默认) required  (需要) 如果ServiceB.methodB() 的事务级别定义为 PROPAGATION_REQUIR...

u010953880的专栏 6016

Spring面试题汇总4:关于Spring事务面试

数据库事务Spring 事务是一般面试都会被提到,很多朋友写惯了代码,很少花时间去整理归纳这些东西,结果本来会的东西,居然吞吞吐吐答不上来。 下面是我收集到一些关于Spring事务的问题,希望能帮助大家过关。 事务是逻辑处理原子性的保证手段,通过使用事务控制,可以极大的避免出现逻辑处理失败导致的脏数据等问题。 事务最重要的两个特性: 事务的传播级别:定义了事务在 传播 方面的控制范围。 数据的隔离级别:定义了事务数据库读写 方面的控制范围。 事务的7种传播级别: 1) PROPAGATION_REQ

Java技术江湖 2529

java 嵌套事务 面试_spring嵌套事务

在所有使用 spring 的应用中, 声明式事务管理可能是使用率最高的功能了, 但是, 从我观察到的情况看,绝大多数人并不能深刻理解事务声明中不同事务传播属性配置的的含义, 让我们来看一下 TransactionDefinition 接口中的定义:/*** Support a current transaction, create a new one if none exists.* Analo...

weixin_39713219的博客 277

关于Spring事务面试

http://www.jfox.info/guan-yu-spring-shi-wu-de-mian-shi-ti By Lee - Last updated: 星期三, 十月 16, 2013 Leave a Comment 数据库事务Spring事务是一般面试都会被提到,很多朋友写惯了代码,很少花时间去整理归纳这些东西,结果本来会的东西,居然吞吞吐吐答不

liangxw1的专栏 3万+

面试官:时候说 Spring事务嵌套

Spring本身是没有事务的,只有数据库才会回有事务,而Spring事务是借助AOP,通过动态代理的方式,在我们要操作数据库的是时候,实际是Spring通过动态代理进行功能扩展,在我们的代码操作数据库之前通过数据库客户端打开数据库事务,如果代码执行完毕没有异常信息或者是没有Spring要捕获的异常信息时,再通过数据库客户端程序提交事务,如果有异常信息或者是有Spring要捕获的异常信息,再通过数据库客户端程序回滚事务,从而达到控制数据库事务的目的。:如果当前存在事务,则在嵌套事务内执行。

2401_85910670的博客 1134

面试官:说说Spring中的事务传播行为

1、前言 在开发中,相信大家都使用过Spring事务管理功能。那么,你是否有了解过,Spring事务传播行为呢? Spring中,有7种类型的事务传播行为。事务传播行为是Spring框架提供的一种事务管理方式,它不是数据库提供的。不知道大家是否听说过“不要在service事务方法中嵌套事务方法,这样会提交多个事务”的说法,其实这是不准确的。了解了事务传播行为之后,相信你就会明白! 2、Sp...

mifffy_java的博客 1727

面试官:工作中,你有遇到过Spring事务失效的时候吗?

失效原因:若指定了特定异常,但实际抛出其他异常,事务不会回滚。示例代码// 不属于BusinessException,不回滚!解决方案:设置覆盖所有异常。Spring事务失效的常见原因可归结为代理机制、异常处理、配置错误三类。在实际开发中,建议:使用public非final方法。统一异常处理逻辑,避免吞异常。通过日志或调试工具检查事务是否生效。掌握这些技巧后,面试官再问“事务为什么失效”,你就能从容应对了!

Like0703的博客 900

面试官Spring事务的传播行为有几种?

Spring中使用事务Spring事务支持两种方式,编程式事务和声明式事务,下面的例子使用声明式事务,即@Transactional注解的方式@Transactional注解应用到pu...

weixin_44747933的博客 1176

面试官Spring事务什么时候会失效?

当某个方法被final修饰时,子类是无法继承和重载的,事务是基于动态代理去实现的,如果某个方法用final修饰了,那么在它的代理类中,就无法重写该方法,而添加事务功能。REQUIRED:如果当前上下文中存在事务,那么加入该事务,如果不存在事务,创建一个事务,这是默认的传播属性值;SUPPORTS:如果当前上下文存在事务,则支持事务加入事务,如果不存在事务,则使用非事务的方式执行;NESTED:如果当前上下文中存在事务,则嵌套事务执行,如果不存在事务,则新建事务;

王二的博客 865

Spring 中如何开启事务

Java 后端面试中,Spring 事务管理是中高级工程师绕不开的话题。面试官不仅想知道你是否会用,更关注你是否理解其作用范围、事务传播机制、异常回滚条件、底层 AOP 实现等细节。理解 Spring 事务的原理与配置,不仅能帮你在面试中脱颖而出,更能在实际开发中避免经典“假提交、未回滚、事务失效”等隐性 Bug。Spring 事务不是仅靠就能解决一切问题,理解其原理 + 范围 + 异常机制 + AOP 动态代理才是硬实力;

残影的博客 886

面试官:你知道哪几种事务失效的场景?

前言 声明式事务Spring功能中最爽之一,可是有些时候,我们在使用声明式事务并未生效,这是为什么呢?今天陈某带大家来聊一聊声明事务的几种失效场景。本文将会从以下两个方面来说一下事务为...

码猿技术专栏 1万+

京东面试:聊聊Spring事务Spring事务的10种失效场景?加入型传播和嵌套型传播有什么区别?

使用spring声明式事务,自动在方法调用之前 (进入一个新的方法),spring会根据事务属性去决定是否开一个事务,并在方法执行之后,决定事务提交或回滚事务。这就是事务的传播。传播行为含义表示当前方法必须运行在事务中。如果当前事务存在,方法将会在该事务中运行。否则,会启动一个新的事务表示当前方法不需要事务上下文,但是如果存在当前事务的话,那么该方法会在这个事务中运行表示该方法必须在事务中运行,如果当前事务不存在,则会抛出一个异常表示当前方法必须运行在它自己的事务中。一个新的事务将被启动。

架构师尼恩 1833

脱离 Spring 实现复杂嵌套事务,之十(实现篇)

为什么80%的码农都做不了架构师?>>> ...

weixin_33912453的博客 205

Spring 事务嵌套无效

Spring Boot 关于嵌套事务无效解决方案 Spring Boot自带事务注解 @Transactional, 只要在方法或者类上加上这个注解,就可以开启事务回滚。当然,是在单个事务的情况下,内嵌事务的时候却不起了作用,如方法A加了这个注解,方法B也加了注解,方法A里调用了方法B,那方法A出现了错误,而方法B没有,那方法B不会进行回滚 代码示例 方法A的代码 @RestController ...

如漩涡的博客 5568

spring嵌套调用事务问题

如果嵌套调用含有事务的方法,在Spring事务管理中,这属于哪个知识点呢?  在当前含有事务方法内部调用其他的方法(无论该方法是否含有事务),这就属于Spring事务传播机制的知识点范畴了。  Spring事务基于Spring AOP,Spring AOP底层用的动态代理,动态代理有两种方式:  1.基于接口代理(JDK代理)基于接口代理  2.基于CGLib代理(子类代理)基于子类代理 下面列举几个事务的例子可以看下是否生效: // Service方法 @Transactional public Empl

weixin_40300139的博客 9674

解惑spring事务传播特性之嵌套事务

在所有使用 spring 的应用中, 声明式事务管理可能是使用率最高的功能了, 但是, 从我观察到的情况看, 绝大多数人并不能深刻理解事务声明中不同事务传播属性配置的的含义, 让我们来看一下 TransactionDefinition 接口中的定义 。 Java代码   /**       * Support a current transaction, cr

零度的博客专栏 1万+

Spring事务理解和配置

文章目录1 Spring事务1.1 事务简介1.1.1 什么是事务1.1.2 事物的特性1.1.3 不考虑事物会引发的安全问题1.1.4 事务隔离级别1.2 事务的传播行为1.3 编程式事务(需要手动写代码,了解)1.3.1 配置平台事务管理器1.3.2 Spring提供了事务管理的模板类1.3.3 在业务层注入事务管理的模板1.3.4 编写事务管理的代码1.4 声明式事务(xml配置)1.4.1 配置事务管理器1.4.2 配置增强1.4.3 AOP的配置1.5 声明式事务(注解)1.5.1 配置事务管理器

Student108的博客 2835

SMT工程师面试试题.pdf

SMT工程师面试试题.pdf

东土 SICOM3024P系列网管型千兆工业以太网交换机产品手册.pdf

东土 SICOM3024P系列网管型千兆工业以太网交换机产品手册pdf,东土 SICOM3024P系列网管型千兆工业以太网交换机产品手册

上一篇: 学会 IDEA 的这个功能,就可以丢掉 Postman 了
下一篇: PO、VO、DAO、BO、DTO、POJO 能分清吗?
互联网架构
博客等级 码龄7年 609粉丝 18原创
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值