文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

Spring 事务 @Transactional注解 面试及原理

2024-11-30 15:00

关注

声明式事务又分为两种:基于XML的声明式事务基于注解的声明式事务。我一般都是通过注解来进行的事务控制。也就是@Transactional

2. 先简单介绍一下@Transactional注解吗?项目中如何使用的?有哪些注意点吗?

我们都是把注解加到需要使用事务控制的方法上,也可以加到类上,加到类上是给类里的所有的方法都加了事务,不建议这样做,这样会增加不需要使用事务的接口的响应时长。

@Transactional注解只能用在public 方法上,如果用在protected或者private的方法上,不会报错,但是该注解不会生效。

@Transactional注解只能回滚非检查型异常,具体为RuntimeException及其子类。

3. Spring 事务中的隔离级别有哪几种?

TransactionDefinition 接口中定义了五个表示隔离级别的常量:

TransactionDefinition.ISOLATION_DEFAULT: 使用后端数据库默认的隔离级别,

Mysql 默认采用的 REPEATABLE_READ隔离级别 Oracle 默认采用的 READ_COMMITTED隔离级别。

TransactionDefinition.ISOLATION_READ_UNCOMMITTED: 最低的隔离级别,允许读取未提交的数据变更,可能会导致脏读、幻读或不可重复读。

TransactionDefinition.ISOLATION_READ_COMMITTED: 允许读取并发事务已经提交的数据,可以阻止脏读,但是幻读或不可重复读仍有可能发生。

TransactionDefinition.ISOLATION_REPEATABLE_READ: 对同一字段的多次读取结果都是一致的,除非数据是被本身事务自己所修改,可以阻止脏读和不可重复读,但幻读仍有可能发生。

TransactionDefinition.ISOLATION_SERIALIZABLE: 最高的隔离级别,完全服从ACID的隔离级别。所有的事务依次逐个执行,这样事务之间就完全不可能产生干扰,也就是说,该级别可以防止脏读、不可重复读以及幻读。但是这将严重影响程序的性能。通常情况下也不会用到该级别。

4. Spring 事务中哪几种事务传播行为?

支持当前事务的情况:

TransactionDefinition.PROPAGATION_REQUIRED: 如果当前存在事务,则加入该事务;

如果当前没有事务,则创建一个新的事务。

TransactionDefinition.PROPAGATION_SUPPORTS: 如果当前存在事务,则加入该事务;

如果当前没有事务,则以非事务的方式继续运行。

TransactionDefinition.PROPAGATION_MANDATORY: 如果当前存在事务,则加入该事务;如果当前没有事务,则抛出异常。(mandatory:强制性)不支持当前事务的情况:

不支持当前事务的情况:

TransactionDefinition.PROPAGATION_REQUIRES_NEW: 创建一个新的事务,

如果当前存在事务,则把当前事务挂起。

TransactionDefinition.PROPAGATION_NOT_SUPPORTED: 以非事务方式运行,

如果当前存在事务,则把当前事务挂起。

TransactionDefinition.PROPAGATION_NEVER: 以非事务方式运行,

如果当前存在事务,则抛出异常。

其他情况:

TransactionDefinition.PROPAGATION_NESTED: 如果当前存在事务,则创建一个事务作为当前事务的嵌套事务来运行;如果当前没有事务,则该取值等价于TransactionDefinition.PROPAGATION_REQUIRED。

5. @Transactional注解只能用在public 方法上,这是为什么?

Spring事务的实现都是依靠AOP,本质上也是依靠代理来实现。事务在spring中的实现其实就是生成bean对象的代理对象。

在bean进行创建出实例时, 如果是有事务注解的方法,就会被进行增强,最终形成代理类。在spring中,有两种动态代理的方式,一种是jdk,它是将原始对象放入代理对象内部,通过调用内含的原始对象来实现原始的业务逻辑,而另一种是cglib,它是通过生成原始对象的子类,子类复写父类的方法,从而实现对父类的增强。

jdk中,如果是private的方法,显然是无法访问的,而在cglib中,也是同样。所以总结来说private方法不能被继承,final方法不能被重写,static方法和继承不相干,所以它们3个的事务不起作用。

Spring选择让protected方法和package方法不支持事务,所以只有public方法支持事务

6. 一个类中没加事务的方法调用加事务的方法,为什么事务失效?怎么解决Spring事务失效的问题?

原因:

Spring事务管理用的是AOP,AOP底层用的是动态代理。所以spring 在扫描bean的时候会扫描方法上是否包含@Transactional注解,如果包含,spring会为这个bean动态地生成一个子类(即代理类,proxy),当这个有注解的方法被调用的时候,实际上是由代理类来调用的,代理类在调用之前就会启动transaction。然而,如果这个有注解的方法是被同一个类中的其他方法调用的,那么该方法的调用并没有通过代理类,而是直接通过原来的那个bean,所以就不会启动transaction。

解决方式:

上面说了:动态代理最终都是要调用原始对象的,而原始对象在去调用方法时,是不会再触发代理了!所以我们就使用代理对象来调用,就会触发事务;

综上解决方案,那怎么获取代理对象呢? 这里提供两种方式:

7. 同一个类中标有@Transactional 的方法A,调用另一个标有@Transactional的 方法B会开启几个事务?

一个事务

Spring事务管理用的是AOP,AOP底层用的是动态代理。所以spring 在扫描bean的时候会扫描方法上是否包含@Transactional注解,如果包含,spring会为这个bean动态地生成一个子类(即代理类,proxy),代理类是继承原来那个bean的。

此时,当这个有注解的方法被调用的时候,实际上是由代理类来调用的,代理类在调用之前就会启动transaction。如果是被同一个类中的其他方法调用的,那么该方法的调用并没有通过代理类,而是直接通过原来的那个bean,所以就不会启动transaction,我们说只有一个事务。

8. 那么如何才能让上面两个方法开启两个事务呢?

1.把方法B抽离到另外一个XXService中去,在这个Service中注入XXService,使用XXService调用方法B;

2.通过在方法内部获得当前类代理对象的方式,通过代理对象调用方法B

上面说了:动态代理最终都是要调用原始对象的,而原始对象在去调用方法时,是不会再触发代理了!所以我们就使用代理对象来调用,就会触发事务;

综上解决方案,那怎么获取代理对象呢? 这里提供两种方式:

1.使用 ApplicationContext 上下文对象获取该对象;

2.使用 AopContext.currentProxy() 获取代理对象,但是需要配置exposeProxy=true

TestService testService = (TestService)AopContext.currentProxy();

testService.B();

同时还需要在B方法将传播行为配置为 @Transactional(propagation = Propagation.REQUIRES_NEW)

9. @Transactional实现原理

注解介绍

@Transactional是spring中声明式事务管理的注解配置方式。@Transactional注解可以帮助我们把事务开启、提交或者回滚的操作,通过aop的方式进行管理。

通过@Transactional注解就能让spring为我们管理事务,免去了重复的事务管理逻辑,减少对业务代码的侵入,使我们开发人员能够专注于业务层面开发。

我们知道实现@Transactional原理是基于spring aop,aop又是动态代理模式的实现,下面我们就详细分析一下实现原理

实现原理

猜想

源码分析

来源:今日头条内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯