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损失生成…...
【大模型RAG】拍照搜题技术架构速览:三层管道、两级检索、兜底大模型
摘要 拍照搜题系统采用“三层管道(多模态 OCR → 语义检索 → 答案渲染)、两级检索(倒排 BM25 向量 HNSW)并以大语言模型兜底”的整体框架: 多模态 OCR 层 将题目图片经过超分、去噪、倾斜校正后,分别用…...
<6>-MySQL表的增删查改
目录 一,create(创建表) 二,retrieve(查询表) 1,select列 2,where条件 三,update(更新表) 四,delete(删除表…...
51c自动驾驶~合集58
我自己的原文哦~ https://blog.51cto.com/whaosoft/13967107 #CCA-Attention 全局池化局部保留,CCA-Attention为LLM长文本建模带来突破性进展 琶洲实验室、华南理工大学联合推出关键上下文感知注意力机制(CCA-Attention),…...
visual studio 2022更改主题为深色
visual studio 2022更改主题为深色 点击visual studio 上方的 工具-> 选项 在选项窗口中,选择 环境 -> 常规 ,将其中的颜色主题改成深色 点击确定,更改完成...
高危文件识别的常用算法:原理、应用与企业场景
高危文件识别的常用算法:原理、应用与企业场景 高危文件识别旨在检测可能导致安全威胁的文件,如包含恶意代码、敏感数据或欺诈内容的文档,在企业协同办公环境中(如Teams、Google Workspace)尤为重要。结合大模型技术&…...
【服务器压力测试】本地PC电脑作为服务器运行时出现卡顿和资源紧张(Windows/Linux)
要让本地PC电脑作为服务器运行时出现卡顿和资源紧张的情况,可以通过以下几种方式模拟或触发: 1. 增加CPU负载 运行大量计算密集型任务,例如: 使用多线程循环执行复杂计算(如数学运算、加密解密等)。运行图…...
【Android】Android 开发 ADB 常用指令
查看当前连接的设备 adb devices 连接设备 adb connect 设备IP 断开已连接的设备 adb disconnect 设备IP 安装应用 adb install 安装包的路径 卸载应用 adb uninstall 应用包名 查看已安装的应用包名 adb shell pm list packages 查看已安装的第三方应用包名 adb shell pm list…...
[大语言模型]在个人电脑上部署ollama 并进行管理,最后配置AI程序开发助手.
ollama官网: 下载 https://ollama.com/ 安装 查看可以使用的模型 https://ollama.com/search 例如 https://ollama.com/library/deepseek-r1/tags # deepseek-r1:7bollama pull deepseek-r1:7b改token数量为409622 16384 ollama命令说明 ollama serve #:…...
Git常用命令完全指南:从入门到精通
Git常用命令完全指南:从入门到精通 一、基础配置命令 1. 用户信息配置 # 设置全局用户名 git config --global user.name "你的名字"# 设置全局邮箱 git config --global user.email "你的邮箱example.com"# 查看所有配置 git config --list…...
【Linux】Linux安装并配置RabbitMQ
目录 1. 安装 Erlang 2. 安装 RabbitMQ 2.1.添加 RabbitMQ 仓库 2.2.安装 RabbitMQ 3.配置 3.1.启动和管理服务 4. 访问管理界面 5.安装问题 6.修改密码 7.修改端口 7.1.找到文件 7.2.修改文件 1. 安装 Erlang 由于 RabbitMQ 是用 Erlang 编写的,需要先安…...
