大话spring,2024年最新java面试高频题

UserService

很显然,以User前缀开头的都是处理t_user表的数据的,在最初的实验中只需要观察这1张表就可以了。

关于UserService接口:

package cn.tedu.service;

public interface UserService {

void update1();

void update2();

}

关于UserServiceImpl类:

package cn.tedu.service.impl;

import cn.tedu.mapper.UserMapper;

import cn.tedu.service.OrderService;

import cn.tedu.service.UserService;

import org.springframework.stereotype.Service;

import org.springframework.transaction.annotation.Transactional;

@Service

public class UserServiceImpl implements UserService {

private UserMapper userMapper;

private OrderService orderService;

public UserServiceImpl(UserMapper userMapper, OrderService orderService) {

this.userMapper = userMapper;

this.orderService = orderService;

}

// TODO-01:调整是否使用以下@Transactional注解,并运行单元测试,以观察效果

// @Transactional

public void update1() {

int rows;

// 更新id=1的数据,会成功

rows = userMapper.updateUserNameById(1, “USER-1000001”);

if (rows != 1) {

throw new RuntimeException(“更新User:id=1数据失败!”);

}

// 更新id=1000000,会失败

rows = userMapper.updateUserNameById(1000000, “USER-1000001”);

if (rows != 1) {

throw new RuntimeException(“更新User:id=1000000数据失败!”);

}

}

// TODO-02:调整是否使用以下@Transactional注解,并运行单元测试,以观察效果

@Transactional

public void update2() {

update1();

}

}

可以看到,以上update1()方法中有2次更新操作,第1次肯定会成功的,第2次则会因为id值不存在而失败,失败后抛出了RuntimeException对象,符合Spring管理事务的默认回滚规则,但是,update1()方法不一定有@Transactional注解,这是苍老师留着我自己测试效果的,下面的update2()就比较简单了,它直接调用了update1()方法。

苍老师写的测试也非常有趣,使用了@Sql注解处理初始化数据库与数据,使用了断言,和我们平时偷懒写的完全不同,那天我也问过他,他说Spring认证考试也会考这个,以后搞不好也会成为用人单位的面试题(毕竟有不少用人单位都是直接上网百度找面试题,根本不自己出错,大家都懂的)……他是这么写的:

package cn.tedu.service;

import cn.tedu.config.ApplicationConfig;

import org.junit.jupiter.api.Test;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.test.context.jdbc.Sql;

import org.springframework.test.context.jdbc.SqlConfig;

import org.springframework.test.context.junit.jupiter.SpringJUnitConfig;

import static org.junit.jupiter.api.Assertions.assertThrows;

@SpringJUnitConfig(ApplicationConfig.class)

@Sql(config = @SqlConfig(dataSource = “dataSource”),

scripts = {“classpath:/sql/schema.sql”, “classpath:/sql/data.sql”})

public class UserServiceTests {

@Autowired

UserService userService;

@Test

public void testUpdate1() {

assertThrows(RuntimeException.class, () -> {

userService.update1();

});

}

@Test

public void testUpdate2() {

assertThrows(RuntimeException.class, () -> {

userService.update2();

});

}

}

其实,现在就可以测试出效果了,根据在业务类中的2个方法上是否使用@Transactional注解,观察数据是否回滚即可判断,我测试的结果如下:

| 是否在update1()上使用注解 | 是否在update2()上使用注解 | 是否回滚 |

| — | — | — |

| 是 | 是 | 是 |

| 否 | 是 | 是 |

| 是 | 否 | 否 |

| 否 | 否 | 否 |

可以看到,事务是否回滚完全取决于update2()方法有没有@Transactional注解,与update1()方法是否有注解无关

苍老师说,Spring官方给出的文档中明确指出:Propagation Rules Are Enforced by a Proxy,即“传播规则是由代理强制执行的”。所以,Spring管理事务是基于接口进行代理的,在调用@Transactional注解的方法之前就会开启事务,并在过程中决定是否回滚或最终提交!

在以上代码中,由于update1()是在update2()内部调用的,不是由代理对象来调用的,所以,执行update2()方法的过程大致上是:

开启事务

执行update2()方法

调用update1()方法

因update1()方法抛出异常且符合回滚规则,执行回滚事务

若未出现回滚,则提交事务(本例会回滚,不会执行这一步)

所以,回到我面试的那个题目,正确的答案应该是:只会在调用update2()方法时开启1个事务,内部调用的update1()根本不是事务性的(不管有没有@Transactional注解),既然只有1个事务,也就不存在事务的传播了

其实,到这里,我的问题已经解决了,但是苍老师还帮我写好了后续的Demo代码,让我更深刻的理解,这可能就是老师的职业病吧,要么不讲,要讲就一讲到底。

接下来就要涉及更新t_order表的数据了,对应的业务接口和业务实现类分别是OrderServiceOrderServiceImpl,关于OrderService接口:

package cn.tedu.service;

public interface OrderService {

void updateSuccessfully();

}

关于OrderServiceImpl类:

package cn.tedu.service.impl;

import cn.tedu.mapper.OrderMapper;

import cn.tedu.service.OrderService;

import org.springframework.stereotype.Service;

import org.springframework.transaction.annotation.Propagation;

import org.springframework.transaction.annotation.Transactional;

@Service

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数Java工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
img
img
img
img
img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,真正体系化!

由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新

如果你觉得这些内容对你有帮助,可以添加V获取:vip1024b (备注Java)
img

最后

面试是跳槽涨薪最直接有效的方式,马上金九银十来了,各位做好面试造飞机,工作拧螺丝的准备了吗?

掌握了这些知识点,面试时在候选人中又可以夺目不少,暴击9999点。机会都是留给有准备的人,只有充足的准备,才可能让自己可以在候选人中脱颖而出。

一个人可以走的很快,但一群人才能走的更远。不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎扫码加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
img

面试是跳槽涨薪最直接有效的方式,马上金九银十来了,各位做好面试造飞机,工作拧螺丝的准备了吗?

掌握了这些知识点,面试时在候选人中又可以夺目不少,暴击9999点。机会都是留给有准备的人,只有充足的准备,才可能让自己可以在候选人中脱颖而出。

[外链图片转存中…(img-xAEESk3S-1712719711488)]

[外链图片转存中…(img-Bgas0RiS-1712719711489)]

一个人可以走的很快,但一群人才能走的更远。不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎扫码加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
[外链图片转存中…(img-u8DPy1cI-1712719711489)]

  • 28
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值