spring中事务相关面试题(自用)
1 什么是spring事务
Spring事务管理的实现原理是基于AOP(面向切面编程)和代理模式。Spring提供了两种主要的方式来管理事务:编程式事务管理和声明式事务管理。
-
声明式事务管理: Spring的声明式事务管理是通过使用注解或XML配置来实现的。它依赖于AOP代理,允许你将事务管理与业务逻辑解耦。@Transactional可以修饰一个类或者一个方法上面。下面是声明式事务管理的实现原理:
- 使用@Transactional注解或XML配置来标识哪些方法应该被事务管理。
- Spring通过AOP代理生成一个代理对象,该代理对象包装了目标对象。
- 当被标记为事务的方法被调用时,代理对象会在方法执行前和方法执行后分别开启和提交事务。
- 如果方法执行过程中发生异常,代理对象会回滚事务。
- 声明式事务管理的配置也可以定义事务传播行为和隔离级别。
-
编程式事务管理: 编程式事务管理要求在代码中明确调用事务管理API。它通常涉及使用
PlatformTransactionManager接口来控制事务的生命周期。以下是编程式事务管理的实现原理:- 创建一个
PlatformTransactionManager实例,通常是Spring提供的实现,如DataSourceTransactionManager。 - 手动开始一个事务,使用
getTransaction()方法获取一个TransactionStatus对象。 - 执行一系列操作。
- 根据操作结果,可以选择提交或回滚事务,使用
commit()和rollback()方法。 - 释放事务资源,通常在
finally块中执行。
- 创建一个
Demo:
在使用编程式事务管理时,Spring会自动处理数据库连接的autocommit。你通常不需要手动将autocommit设置为false,因为Spring的事务管理器会在事务开始时将其设置为false,以确保事务的原子性。
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.DefaultTransactionDefinition;@SpringBootApplication
public class TransactionExampleApplication {@Autowiredprivate UserService userService;public static void main(String[] args) {SpringApplication.run(TransactionExampleApplication.class, args);}@Beanpublic PlatformTransactionManager transactionManager() {return new DataSourceTransactionManager(dataSource());}@Beanpublic DataSource dataSource() {// Configure your data source here}public void performTransaction() {PlatformTransactionManager transactionManager = transactionManager();DefaultTransactionDefinition def = new DefaultTransactionDefinition();TransactionStatus status = transactionManager.getTransaction(def);try {userService.createUser("User1");userService.createUser("User2");// Simulate an errorint i = 1 / 0; // This will cause an exceptiontransactionManager.commit(status);} catch (Exception e) {transactionManager.rollback(status);}}
}@Service
class UserService {@Autowiredprivate JdbcTemplate jdbcTemplate;public void createUser(String username) {jdbcTemplate.update("INSERT INTO users (username) VALUES (?)", username);}
}
2 什么是spring事务传播行为
大体解释一下事务:在spring中事务可以指一个执行多条sql语句的方法
什么是事务传播行为呢:一个事务方法A在方法体中调用另一个事务方法B,不管事务A、B是在同一个类中还是不同的类中这样都叫事务的传播行为。
Spring定义了以下几种事务传播行为:
- REQUIRED(默认)--required:如果当前存在事务,则加入该事务;如果当前没有事务,则创建一个新事务。
- REQUIRES_NEW:创建一个新事务,并挂起当前事务(如果存在)。
- SUPPORTS:如果当前存在事务,则加入该事务;如果当前没有事务,则以非事务方式执行。
- MANDATORY:要求当前存在事务,否则抛出异常。
- NOT_SUPPORTED:以非事务方式执行操作,挂起当前事务(如果存在)。
- NEVER:以非事务方式执行操作,如果当前存在事务,则抛出异常。
- NESTED:如果当前存在事务,则创建一个嵌套事务;如果当前没有事务,则创建一个新事务。嵌套事务是独立于外部事务的子事务,可以独立提交或回滚。
通过配置这些传播行为,可以实现复杂的事务嵌套和控制,以满足不同业务场景的需求。Spring的事务管理机制使事务管理变得更容易,同时提供了灵活性和可维护性,使开发者能够更好地控制事务的行为。
光看概念难以很好的理解,下面给出具体情境代码说明:
场景 1:REQUIRED(默认传播行为)
假设你有一个订单服务(OrderService)和一个支付服务(PaymentService)。在处理订单时,你需要创建订单记录并在支付服务中进行付款。订单服务的createOrder方法和支付服务的makePayment方法都使用@Transactional注解,并默认传播行为为REQUIRED
@Service
public class OrderService {@Autowiredprivate OrderRepository orderRepository;@Autowiredprivate PaymentService paymentService;@Transactionalpublic void createOrder(Order order) {// 创建订单记录orderRepository.save(order);// 调用支付服务paymentService.makePayment(order);}
}
@Service
public class PaymentService {@Transactionalpublic void makePayment(Order order) {// 处理支付逻辑}
}
在这种情况下,当你在订单服务中调用createOrder方法时,它会启动一个新的事务。如果在makePayment方法中发生异常,整个事务将回滚,包括订单创建。这是因为REQUIRED传播行为表示要么加入现有事务,要么创建新事务。
场景 2:REQUIRES_NEW(新事务传播行为)
现在,假设你想要在订单服务中调用支付服务,但无论支付服务的事务成功或失败,订单服务的事务都必须继续。在这种情况下,你可以将支付服务的传播行为配置为REQUIRES_NEW。
@Service
public class OrderService {@Autowiredprivate OrderRepository orderRepository;@Autowiredprivate PaymentService paymentService;@Transactionalpublic void createOrder(Order order) {// 创建订单记录orderRepository.save(order);// 调用支付服务paymentService.makePayment(order);}
}
@Service
public class PaymentService {@Transactional(propagation = Propagation.REQUIRES_NEW)public void makePayment(Order order) {// 处理支付逻辑}
}
在这种情况下,当你在订单服务中调用createOrder方法时,订单服务的事务会启动。然后,它调用支付服务的makePayment方法,该方法会启动一个新的独立事务。如果支付服务的事务失败,仅该事务会回滚,而订单服务的事务仍然会继续。
这两个场景说明了不同的事务传播行为如何影响方法之间的事务交互。REQUIRED传播行为将方法加入现有事务或创建新事务,而REQUIRES_NEW传播行为会创建一个新事务,独立于外部事务。选择适当的传播行为取决于你的业务需求。
那么现在最重要的问题来了:
还是以两个事务为例,在每个事务都可以设置7中事务传播行为,两个事务传播方式就有49中,所以能能正确理解各个事务类型的概念将十分重要
以下举例一些事务传播的组合方式:
- REQUIRED ------》REQUIRES_NEW A事务没有就新建,B事务不会加入A,独立执行,B事务发生异常不会回滚到A
- REQUIRED -----》 REQUIRED A事务没有就创建 B事务会先判断有没有事务,有就加入,所以A,B同在一个事务,B发生异常会回滚到A
- REQUIRES_NEW ------》REQUIRED A事务没有就创建,B事务加入A事务,A,B同属一个事务,B事务发生异常不会回滚到A
通过三面三个例子就能清楚的了解REQUIRED REQUIRES_NEW 这两种行为,REQUIRED 如果没有就创建,有就加入,不独立与其他事务。而REQUIRES_NEW 在没有事务时创建事务,有时加入其他事务中,但是REQUIRES_NEW 具有独立性,不会影响其他事务,也不会被其他事务影响而回滚
解释一下REQUIRES_NEW 与SUPPORTS,容易混淆,比如REQUIRED --》REQUIRES_NEW 与REQUIRED --》SUPPORTS 这两种,后者发生异常都不会回滚到之前的事务,具有独立性,REQUIRES_NEW 与SUPPORTS的区别在于之前没有外部事务,REQUIRES_NEW 会创建事务,而SUPPORTS以非事务执行,这就是我认为的唯一区别
综上:REQUIRED REQUIRES_NEW SUPPORTS 无论怎么随机组合就能理解了
接下来继续讨论:NOT_SUPPORTED , REQUIRES_NEW----》NOT_SUPPORTED 后者不会加入事务,直接是非事务执行,具有独立性。 NOT_SUPPORTED与SUPPORTS的区别就是当之前有外部事务时NOT_SUPPORTED修饰的方法根本不会作为一个事务,而SUPPORTS会加入之前的事务,具有事务的ACID特性
综上我们已经弄懂REQUIRED REQUIRES_NEW SUPPORTS NOT_SUPPORTED
最后再来一个多传播行为的思考:REQUIRED REQUIRES_NEW SUPPORTS NOT_SUPPORTED 分别对应四个事务ABCB
A事务方法体中{
调用B
调用C
调用D
}
这时如果B事务发生异常,会怎样?B会回滚,不影响事务A。C加入A事务执行。D以非事务执行。
我们换一下再来思考:
A事务方法体中{
调用B
}
B事务方法体中 {
调用C
调用D
}
以上调用B出现异常会怎样?B会回滚,那么B中调用的方法都会回滚。
还有3中传播行为没讲,自己去理解吧。
相关文章:
spring中事务相关面试题(自用)
1 什么是spring事务 Spring事务管理的实现原理是基于AOP(面向切面编程)和代理模式。Spring提供了两种主要的方式来管理事务:编程式事务管理和声明式事务管理。 声明式事务管理: Spring的声明式事务管理是通过使用注解或XML配置来…...
09 | JpaSpecificationExecutor 解决了哪些问题
QueryByExampleExecutor用法 QueryByExampleExecutor(QBE)是一种用户友好的查询技术,具有简单的接口,它允许动态查询创建,并且不需要编写包含字段名称的查询。 下面是一个 UML 图,你可以看到 QueryByExam…...
Linux命令(93)之su
linux命令之su 1.su介绍 linux命令su用于变更为其它使用者的身份,如root用户外,需要输入使用者的密码 2.su用法 su [参数] user su参数 参数说明-c <command>执行指定的命令,然后切换回原用户-切换到目标用户的环境变量 3.实例 3…...
1.HTML-HTML解决中文乱码问题
题记 下面是html文件解决中文乱码的方法 方法一 在 HTML 文件的 <head> 标签中添加 <meta charset"UTF-8">,确保文件以 UTF-8 编码保存 <head> <meta charset"UTF-8"> <!-- 其他标签和内容 --> </head> --…...
Vue3 + Nodejs 实战 ,文件上传项目--实现拖拽上传
目录 1.拖拽上传的剖析 input的file默认拖动 让其他的盒子成为拖拽对象 2.处理文件的上传 处理数据 上传文件的函数 兼顾点击事件 渲染已处理过的文件 测试效果 3.总结 博客主页:専心_前端,javascript,mysql-CSDN博客 系列专栏:vue3nodejs 实战-…...
Windows:VS Code IDE安装ESP-IDF【保姆级】
物联网开发学习笔记——目录索引 参考: VS Code官网:Visual Studio Code - Code Editing. Redefined 乐鑫官网:ESP-IDF 编程指南 - ESP32 VSCode ESP-ID Extension Install 一、前提条件 Visual Studio Code IDE安装ESP-IDF扩展…...
Hadoop3教程(十一):MapReduce的详细工作流程
文章目录 (94)MR工作流程Map阶段Reduce阶段 参考文献 (94)MR工作流程 本小节将展示一下整个MapReduce的全工作流程。 Map阶段 首先是Map阶段: 首先,我们有一个待处理文本文件的集合; 客户端…...
测试中Android与IOS分别关注的点
目录 1、自身不同点 2、测试注重点 3、其他测试点 主要从本身系统的不同点、系统造成的不同点、和注意的测试点做总结 1、自身不同点 研发商:Adroid是google公司做的手机系统,IOS是苹果公司做的手机系统 开源程度:Android是开源的&a…...
NLG(自然语言生成)评估指标介绍
诸神缄默不语-个人CSDN博文目录 本文介绍自然语言生成任务中的各种评估指标。 因为我是之前做文本摘要才接触到这一部分内容的,所以本文也是文本摘要中心。 持续更新。 文章目录 1. 常用术语2. ROUGE (Recall Oriented Understudy for Gisting Evaluation)1. 计算…...
苍穹外卖(七) Spring Task 完成订单状态定时处理
Spring Task 完成订单状态定时处理, 如处理支付超时订单 Spring Task介绍 Spring Task 是Spring框架提供的任务调度工具,可以按照约定的时间自动执行某个代码逻辑。 应用场景: 信用卡每月还款提醒 火车票售票系统处理未支付订单 入职纪念日为用户发送通知 点外…...
【探索Linux】—— 强大的命令行工具 P.11(基础IO,文件操作)
阅读导航 前言一、C语言的文件操作二、C的文件操作三、Linux系统文件操作(I/O接口)1. open()⭕传入多个打开方式(按位或操作将不同的标志位组合在一起) 2. write()3. read()4. close()5. lseek() 温馨提示 前言 前面我们讲了C语言…...
前端练习项目(附带页面psd图片及react源代码)
一、前言 相信很多学完前端的小伙伴都想找个前端项目练练手,检测自己的学习成果。但是现在很多项目市面上都烂大街了。今天给大家推荐一个全新的项目——电子校园 项目位置:https://github.com/v5201314/eSchool 二、项目介绍(部分页面展示)ÿ…...
【从零开始学习Redis | 第三篇】在Java中操作Redis
前言: 本文算是一期番外,介绍一下如何在Java中使用Reids ,而其实基于Java我们有很多的开源框架可以用来操作redis,而我们今天选择介绍的是其中比较常用的一款:Spring Data Redis 目录 前言: Spring Data…...
vim、gcc/g++、make/Makefile、yum、gdb
vim、gcc/g、make/Makefile、yum、gdb 一、Linux编辑器vim1、简介2、三种模式的概念(1)正常/普通/命令模式(Normal mode)(2)插入模式(Insert mode)(3)末行/底行模式(last line mode) 3、三种模式的切换4、正…...
2022最新版-李宏毅机器学习深度学习课程-P13 局部最小值与鞍点
一、优化失败的原因 局部最小值?鞍点? 二、数学推导分析 用泰勒公式展开 一项与梯度(L的一阶导)有关,一项与海赛矩阵(L的二阶导)有关 海瑟矩阵 VTHV通过海瑟矩阵的性质可以转为判断H是否是正…...
ARM架构的基本知识
ARM两种授权 体系结构授权, 一种硬件规范, 用来约定指令集, 芯片内部体系结构(内存管理, 高速缓存管理), 只约定每一条指令的格式, 行为规范, 参数, 客户根据这个规范自行设计与之兼容的处理器处理IP授权, ARM公司根据某个版本的体系结构设计处理器, 再把处理器设计方案授权给…...
网络安全(黑客技术)——如何高效自学
前言 前几天发布了一篇 网络安全(黑客)自学 没想到收到了许多人的私信想要学习网安黑客技术!却不知道从哪里开始学起!怎么学?如何学? 今天给大家分享一下,很多人上来就说想学习黑客,…...
云原生场景下高可用架构的最佳实践
作者:刘佳旭(花名:佳旭),阿里云容器服务技术专家 引言 随着云原生技术的快速发展以及在企业 IT 领域的深入应用,云原生场景下的高可用架构,对于企业服务的可用性、稳定性、安全性越发重要。通…...
图论-最短路径算法-弗洛伊德算法与迪杰斯特拉算法
弗洛伊德算法: 弗洛伊德算法本质是动态规划,通过添加点进如可选择的点组成的集合的同时更新所有点之间的距离,从而得到每两个点之间的最短距离。 初始化: 创建一个二维数组 dist,其中 dist[i][j] 表示从节点 i 到节点…...
[23] IPDreamer: Appearance-Controllable 3D Object Generation with Image Prompts
pdf Text-to-3D任务中,对3D模型外观的控制不强,本文提出IPDreamer来解决该问题。在NeRF Training阶段,IPDreamer根据文本用ControlNet生成参考图,并将参考图作为Zero 1-to-3的控制条件,用基于Zero 1-to-3的SDS损失生成…...
手游刚开服就被攻击怎么办?如何防御DDoS?
开服初期是手游最脆弱的阶段,极易成为DDoS攻击的目标。一旦遭遇攻击,可能导致服务器瘫痪、玩家流失,甚至造成巨大经济损失。本文为开发者提供一套简洁有效的应急与防御方案,帮助快速应对并构建长期防护体系。 一、遭遇攻击的紧急应…...
java_网络服务相关_gateway_nacos_feign区别联系
1. spring-cloud-starter-gateway 作用:作为微服务架构的网关,统一入口,处理所有外部请求。 核心能力: 路由转发(基于路径、服务名等)过滤器(鉴权、限流、日志、Header 处理)支持负…...
<6>-MySQL表的增删查改
目录 一,create(创建表) 二,retrieve(查询表) 1,select列 2,where条件 三,update(更新表) 四,delete(删除表…...
1688商品列表API与其他数据源的对接思路
将1688商品列表API与其他数据源对接时,需结合业务场景设计数据流转链路,重点关注数据格式兼容性、接口调用频率控制及数据一致性维护。以下是具体对接思路及关键技术点: 一、核心对接场景与目标 商品数据同步 场景:将1688商品信息…...
汽车生产虚拟实训中的技能提升与生产优化
在制造业蓬勃发展的大背景下,虚拟教学实训宛如一颗璀璨的新星,正发挥着不可或缺且日益凸显的关键作用,源源不断地为企业的稳健前行与创新发展注入磅礴强大的动力。就以汽车制造企业这一极具代表性的行业主体为例,汽车生产线上各类…...
生成 Git SSH 证书
🔑 1. 生成 SSH 密钥对 在终端(Windows 使用 Git Bash,Mac/Linux 使用 Terminal)执行命令: ssh-keygen -t rsa -b 4096 -C "your_emailexample.com" 参数说明: -t rsa&#x…...
RNN避坑指南:从数学推导到LSTM/GRU工业级部署实战流程
本文较长,建议点赞收藏,以免遗失。更多AI大模型应用开发学习视频及资料,尽在聚客AI学院。 本文全面剖析RNN核心原理,深入讲解梯度消失/爆炸问题,并通过LSTM/GRU结构实现解决方案,提供时间序列预测和文本生成…...
【Linux】Linux 系统默认的目录及作用说明
博主介绍:✌全网粉丝23W,CSDN博客专家、Java领域优质创作者,掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域✌ 技术范围:SpringBoot、SpringCloud、Vue、SSM、HTML、Nodejs、Python、MySQL、PostgreSQL、大数据、物…...
比较数据迁移后MySQL数据库和OceanBase数据仓库中的表
设计一个MySQL数据库和OceanBase数据仓库的表数据比较的详细程序流程,两张表是相同的结构,都有整型主键id字段,需要每次从数据库分批取得2000条数据,用于比较,比较操作的同时可以再取2000条数据,等上一次比较完成之后,开始比较,直到比较完所有的数据。比较操作需要比较…...
Linux部署私有文件管理系统MinIO
最近需要用到一个文件管理服务,但是又不想花钱,所以就想着自己搭建一个,刚好我们用的一个开源框架已经集成了MinIO,所以就选了这个 我这边对文件服务性能要求不是太高,单机版就可以 安装非常简单,几个命令就…...
