【Spring面试】八、事务相关
文章目录
- Q1、事务的四大特性是什么?
- Q2、Spring支持的事务管理类型有哪些?Spring事务实现方式有哪些?
- Q3、说一下Spring的事务传播行为
- Q4、说一下Spring的事务隔离
- Q5、Spring事务的实现原理
- Q6、Spring事务传播行为的实现原理是什么?
- Q7、Spring多线程事务,能否保证事务的一致性?
- Q8、Spring事务失效的原因?
Q1、事务的四大特性是什么?
答案:
即ACID:
- 原子性,Atomicity,即事务包含的所有操作要么同成功,要么同失败
- 一致性,Cosistency,即事务必须使得数据库从一个一致性状态到两一个一致性状态。如用户A和用户B两者的钱加起来一共5000,那么不管A和B之间如何转账,转几次账,事务结束后两个用户的钱相加来应该还得是5000,这就是事务的一致性
- 隔离性,Isolation,多个事务并发时,之间要相互隔离,不能被其他事务干扰
- 持久性,Durability,事务一旦提交,对数据库中数据的改变就是永久的,即使数据库故障也不会丢失提交事务的操作
Q2、Spring支持的事务管理类型有哪些?Spring事务实现方式有哪些?
答案: 支持的事务管理类型有两种
Spring支持两种类型的事务管理:
- 编程式事务管理:灵活性高,但难维护
@Autowired
TransactionTemplate transactionTemplate ;
- 声明式事务管理:业务代码和事务管理分离,只需用注解和xml配置来管理事务。以下为基于注解
@Transactional
:
答案: 实现声明式事务的三种方式
- 基于接口:Spring早期版本时用,更接近底层源码,有基于TransactionInterceptor的声明式事务,基于TransactionProxyFactoryBean的声明式事务
- 基于
<tx>和<aop>
的xml声明式事务管理:和Spring AOP结合,利用切点表达式使得事务管理更加灵活 - 基于@Transactional的全注解方式:在需要实施事务管理的方法或者类上加@Transactional注解,指定事务规则即可实现事务管理
Q3、说一下Spring的事务传播行为
答案:
两个事务方法之间的嵌套调用时
,这个事务方法如何进行,即事务的传播特性。
@Transactional
public void trans(){sub();log();query();}@Transactional //SUPPORTS
public info query(){}@Transactional //REQUIRES_NEW
public void log(){}
以上面的query方法为例,其用SUPPORTS,即单独执行时不开启事务(就一个查询,当然不用开启),被有事务的外部方法调用时,则融入到这个外部方法的事务中,与他们同成功,同失败。(到大学了,和其余室友住一个屋子,还是你自己外面租一个新房子)
Q4、说一下Spring的事务隔离
答案:
事务隔离用来解决并发事务所产生的一些问题:
- 脏读
- 不可重复读
- 幻影读
通过设置不同的隔离级别,可解决以上问题。
脏读:
事务2只是改了余额,但并未提交,事务1就把这个没提交的值读走了,如果以后事务2最终回滚,就出问题了。即一个事务读取了另一个事务中没有提交的数据,会在本事务中产生数据不一致的问题。
@Transactional(isolation = isolation.READ_COMMITTED)
设置事务隔离策略为读已提交,只读别的并发事务已提交的修改
。
不可重复读:
事务1先读后去处理其他事儿,然后期间事务2修改并commit,等事务1再读,则产生数据不一致的问题。
@Transactional(isolation = isolation.REPEATABLE_READ)
设置事务隔离策略为可重复读REPEATABLE_READ,确保事务1可以多次从一个字段中读到相同的值,即事务1执行期间禁止其他事务对这个字段进行更新(行锁)
。
幻影读:
不可重复读是针对一行数据,而幻影读则是针对整个表
,比如两次读取,表中多出了一行数据:
即一个事务所在的方法中,多次进行整表数据读取,结果不一样,产生数据不一致问题。
@Transactional(isolation = isolation.SERIALIZABLE)
需要设置事务级别为串行化SERIALIZABLE
,确保事务1可以多次从一个表中读到相同的行数,事务1执行期间,禁止其他事务对这个表进行增删改,但这样性能十分低下(表锁)
最后,当不设置事务隔离级别时,将默认使用底层所选数据库自身的默认事务隔离级别。
SELECT @@tx_isolation;
Q5、Spring事务的实现原理
以JavaConfig的方式为例,使用是:
//启动事务,这样可以使用@Transactional注解
@EnableTransactionManagement
答案:
没有Spring之前,单靠JDBC来操作是这样的:
try {//...//将事务提交机制改为手动提交conn.setAutoCommit(false);//业务逻辑//在这里事务结束,手动提交数据conn.commit();}
Spring事务是把上面业务逻辑前后的事务开启与提交用AOP包了一下,即原理是:Spring事务底层是基于数据库事务和AOP机制。
- 为使用了@Transactional注解的Bean创建一个动态代理对象(bean初始化后调用bean的后置处理器来创建动态代理)
- 如果是事务方法(类上面、接口上面、方法上面、接口方法上面),则开启事务:
try{- 创建数据库连接- 修改数据库连接的autocommit属性为false,禁止此连接自动提交- 执行当前方法,方法中会执行数据库操作的业务SQL-
}catch{- 若出现异常,且这个异常需要回滚,则回滚事务
}
- 没有发生异常,则提交事务
Q6、Spring事务传播行为的实现原理是什么?
答案:
Spring的事务信息是存于ThreadLocal中的,所以一个线程永远只能有一个事务。对于被调用的事务方法,当:
- 融入:当传播行为是融入外部事务,则拿到ThreadLocal中的Connection,共享一个数据库连接,来共同提交与回滚
- 创建新事务:当传播行为是创建新的事务,则会把嵌套的新事务存入ThreadLocal,再将外部暂存起来,当嵌套事务提交或回滚后,再将暂存的外部事务信息恢复到ThreadLocal来提交或回滚
详细流程:
- 外部:创建数据库连接Connection并存入ThreadLocal,修改数据库连接的autocommit属性为false
- 外部:返回事务状态信息(
TransactionInfo.newTransaction=true
) - 外部:往下执行方法,中途发现
内部调用了另一个事务方法
- 内嵌:判断当前ThreadLoacl是否已有Connection,有即是内嵌事务,需要判断事务传播行为,到此分两种情况
情况一,当传播行为是融入
:
- 不会创建connection,返回事务状态信息(
TransactionInfo.newTransaction=false
),即不是一个新事务 - 内部被调用的事务方法开始执行相关SQL
- 执行完后,判断TransactionInfo.newTransaction是否为true,此时是融入,这个值为false,不提交
- 内部被调用的事务方法执行完成
- 外部方法继续往下执行
- 执行完后判断TransactionInfo.newTransaction是否为true,外部为true
- 拿到ThreadLocal中的connection进行提交
情况二,当传播行为是创建新的事务
:
- 把外层方法事务相关的事务信息(包括connection、隔离级别、是否只读…)暂存到TransactionInfo中,同时会把ThreadLocal中的事务信息置空
- 创建新的connection,返回事务状态信息(
TransactionInfo.newTransaction=true
),即新事务,并放入ThreadLocal当中 - 内部被调用的事务方法往下执行
- 执行完后判断TransactionInfo.newTransaction是否为true⇒是⇒于是提交
- 判断是否暂存了事务 ⇒ 是⇒ 再把上面暂存的外部方法的事务信息放回ThreadLocal中
- 内部被调用的事务方法执行完成
- 外部事务方法接着执行
- 执行完后判断TransactionInfo.newTransaction是否为true,外部为true
- 拿到ThreadLocal中的connection进行提交
Q7、Spring多线程事务,能否保证事务的一致性?
问题分析:两个事务方法A和B,在两个线程中,对应的事务能否同时提交或回滚?
答案:
Spring不支持,因为Spring事务信息存于ThreadLocal中的Connection,一个线程永远只能有一个事务,所以无法实现两个事务的一致性。可以通过编程式事务自己控制或者分布式事务来解决(二阶段提交的方式)。
Q8、Spring事务失效的原因?
Spring事务底层是基于数据库事务和AOP机制,因此,参考AOP失效,可以知道Spring事务失效的原因:
答案:
- 方法的内部调用导致事务传播失效
- 方法是private会失效,解决: 改成public
- 目标类没有配置为Bean也会失效 解决: 配置为Bean,交给Spring管理
- 自己捕获了异常 解决: 不要捕获处理
- 使用cglib动态代理,但是@Transactional声明在接口上面
后面几种本质上是使用不当导致的失效。
相关文章:
【Spring面试】八、事务相关
文章目录 Q1、事务的四大特性是什么?Q2、Spring支持的事务管理类型有哪些?Spring事务实现方式有哪些?Q3、说一下Spring的事务传播行为Q4、说一下Spring的事务隔离Q5、Spring事务的实现原理Q6、Spring事务传播行为的实现原理是什么?…...
Windows平台Qt6中UTF8与GBK文本编码互相转换、理解文本编码本质
快速答案 UTF8转GBK QString utf8_str"中UTF文"; std::string gbk_str(utf8_str.toLocal8Bit().data());GBK转UTF8 std::string gbk_str_given_by_somewhere"中GBK文"; QString utf8_strQString::fromLocal8Bit(gbk_str_given_by_somewhere.data());正文…...
【探索Linux】—— 强大的命令行工具 P.9(进程地址空间)
阅读导航 前言一、内存空间分布二、什么是进程地址空间1. 概念2. 进程地址空间的组成 三、进程地址空间的设计原理1. 基本原理2. 虚拟地址空间 概念 大小和范围 作用 虚拟地址空间的优点 3. 页表 四、为什么要有地址空间五、总结温馨提示 前言 前面我们讲了C语言的基础知识&am…...
ESP32主板-MoonESP32
产品简介 Moon-ESP32主板,一款以双核芯片ESP32-E为主芯片的主控板,支持WiFi和蓝牙双模通信,低功耗,板载LED指示灯,引出所有IO端口,并提供多个I2C端口、SPI端口、串行端口,方便连接,…...
Python 图片处理笔记
import numpy as np import cv2 import os import matplotlib.pyplot as plt# 去除黑边框 def remove_the_blackborder(image):image cv2.imread(image) #读取图片img cv2.medianBlur(image, 5) #中值滤波,去除黑色边际中可能含有的噪声干扰#medianBlur( Inp…...
SpringCloud Ribbon--负载均衡 原理及应用实例
😀前言 本篇博文是关于SpringCloud Ribbon的基本介绍,希望你能够喜欢 🏠个人主页:晨犀主页 🧑个人简介:大家好,我是晨犀,希望我的文章可以帮助到大家,您的满意是我的动力…...
Redis的介绍以及简单使用
Redis(Remote Dictionary Server)是一个开源的内存数据存储系统,它以键值对的形式将数据存在内存中,并提供灵活、高性能的数据访问方式。Redis具有高速读写能力和丰富的数据结构支持,可以广泛应用于缓存、消息队列、实…...
ad18学习笔记十二:如何把同属性的元器件全部高亮?
1、先选择需要修改的器件的其中一个。 2、右键find similar objects,然后在弹出的对话框中,将要修改的属性后的any改为same 3、像这样勾选的话,能把同属性的元器件选中,其他器件颜色不变 注意了,如果这个时候ÿ…...
SpringSecurity 核心过滤器——SecurityContextPersistenceFilter
文章目录 前言过滤器介绍用户信息的存储获取用户信息存储用户信息获取用户信息 处理逻辑总结 前言 SecurityContextHolder,这个是一个非常基础的对象,存储了当前应用的上下文SecurityContext,而在SecurityContext可以获取Authentication对象…...
反转单链表
思路图1: 代码: struct ListNode* reverseList(struct ListNode* head){if(headNULL)//当head是空链表时 {return head; }struct ListNode* n1NULL;struct ListNode* n2head;struct ListNode* n3head->next;if(head->nextNULL)//当链表只有一个节…...
加速新药问世,药企如何利用云+网的优势?
随着计算能力的不断提高和人工智能技术的迅速发展,药物研发领域正迎来一场革命。云端强大的智能算法正成为药物研发企业的得力助手,推动着药物的精确设计和固相筛选。这使得药物设计、固相筛选以及药物制剂开发的时间大幅缩短,有望加速新药物…...
C++中string对象之间比较、char*之间比较
#include <cstring> //char* 使用strcmp #include <string> //string 使用compare #include <iostream> using namespace std; int main() {string stringStr1 "42";string stringStr2 "42";string stringStr3 "213";cout …...
MVVM模式理解
链接: MVVM框架理解及其原理实现 - 知乎 (zhihu.com) 重点: 1.将展示的界面窗口和创建的构件是数据进行分离 2.利用一个中间商进行数据的处理,所有的数据通过中间商进行处理...
js常用的数组处理方法
some 方法 用于检查数组中是否至少有一个元素满足指定条件。如果有满足条件的元素,返回值为 true,否则返回 false。 const numbers [1, 2, 3, 4, 5];const hasEvenNumber numbers.some((number) > number % 2 0); console.log(hasEvenNumber); /…...
[Document]VectoreStoreToDocument开发
该document是用来检索文档的。 第一步:定义组件对象,该组件返回有两种类型:document和text。 第二步:获取需要的信息,向量存储库,这里我使用的是内存向量存储(用该组件拿到文档,并检…...
【LeetCode-简单题】225. 用队列实现栈
文章目录 题目方法一:单个队列实现 题目 方法一:单个队列实现 入栈 和入队正常进行出栈的元素其实就是队列的尾部元素,所以直接将尾部元素弹出即可,其实就可以将除了最后一个元素的其他元素出队再加入队,然后弹出队首元…...
数据预处理方式合集
删除空行 #del all None value data_all.dropna(axis1, howall, inplaceTrue) 删除空列 #del all None value data_all.dropna(axis0, howall, inplaceTrue) 缺失值处理 观测缺失值 观测数据缺失值有一个比较好用的工具包——missingno,直接传入DataFrame&…...
【前端】jquery获取data-*的属性值
通过jquery获取下面data-id的值 <div id"getId" data-id"122" >获取id</div> 方法一:dataset()方法 //data-前缀属性可以在JS中通过dataset取值,更加方便 console.log(getId.dataset.id);//112//赋值 getId.dataset.…...
GB28181学习(五)——实时视音频点播(信令传输部分)
要求 实时视音频点播的SIP消息应通过本域或其他域的SIP服务器进行路由、转发,目标设备的实时视音频流宜通过本域的媒体服务器进行转发;采用INVITE方法实现会话连接,采用RTP/RTCP协议实现媒体传输;信令流程分为客户端主动发起和第…...
单例模式(饿汉模式 懒汉模式)与一些特殊类设计
文章目录 一、不能被拷贝的类 二、只能在堆上创建类对象 三、只能在栈上创建类对象 四、不能被继承的类 五、单例模式 5、1 什么是单例模式 5、2 什么是设计模式 5、3 单例模式的实现 5、3、1 饿汉模式 5、3、1 懒汉模式 🙋♂️ 作者:Ggggggtm &#x…...
133. 克隆图
133. 克隆图 题目-中等难度示例1. bfs 题目-中等难度 给你无向 连通 图中一个节点的引用,请你返回该图的 深拷贝(克隆)。 图中的每个节点都包含它的值 val(int) 和其邻居的列表(list[Node])。…...
交流耐压试验目的
试验目的 交流耐压试验是鉴定电力设备绝缘强度最有效和最直接的方法。 电力设备在运行中, 绝缘长期受着电场、 温度和机械振动的作用会逐渐发生劣化, 其中包括整体劣化和部分劣化,形成缺陷, 例如由于局部地方电场比较集中或者局部…...
使用 YCSB 和 PE 进行 HBase 性能压力测试
HBase主要性能压力测试有两个,一个是 HBase 自带的 PE,另一个是 YCSB,先简单说一个两者的区别。PE 是 HBase 自带的工具,开箱即用,使用起来非常简单,但是 PE 只能按单个线程统计压测结果,不能汇…...
正则表达式相关概念及不可见高度页面的获取
12.正则 概念:匹配有规律的字符串,匹配上则正确 1.正则的创建方式 构造函数创建 // 修饰符 igm// i 忽视 ignore// g global 全球 全局// m 换行 var regnew RegExp("匹配的内容","修饰符")var str "this is a Box";var reg new RegExp(&qu…...
深入学习 Redis - 分布式锁底层实现原理,以及实际应用
目录 一、Redis 分布式锁 1.1、什么是分布式锁 1.2、分布式锁的基础实现 1.2.1、引入场景 1.2.2、基础实现思想 1.2.3、引入 setnx 1.3、引入过期时间 1.4、引入校验 id 1.5、引入 lua 脚本 1.5.1、引入 lua 脚本的原因 1.5.2、lua 脚本介绍 1.6、过期时间续约问题&…...
Hive行转列[一行拆分成多行/一列拆分成多列]
场景: hive有张表armmttxn_tmp,其中有一个字段lot_number,该字段以逗号分隔开多个值,每个值又以冒号来分割料号和数量,如:A3220089:-40,A3220090:-40,A3220091:-40,A3220083:-40,A3220087:-40,A3220086:-4…...
TypeScript系列之类型 string
文章の目录 背景写在最后 背景 与JavaScript不同的是,TypeScript使用的是静态类型,比如说它指定了变量可以保存的数据类型。如下面代码所示,如果在JavaScript中,指定变量可以保存的数据类型,会报错:类型注…...
【C++】动态内存管理 ③ ( C++ 对象的动态创建和释放 | new 运算符 为类对象 分配内存 | delete 运算符 释放对象内存 )
文章目录 一、C 对象的动态创建和释放1、C 语言 对象的动态创建和释放 的方式2、C 语言 对象的动态创建和释放 的方式 二、代码示例 - 对象的动态创建和释放 一、C 对象的动态创建和释放 使用 C 语言中的 malloc 函数 可以为 类对象 分配内存 ; 使用 free 函数可以释放上述分配…...
AMS爆炸来袭,上线即巅峰
1.关于首发项目Antmons(AMS)空投结果 Gate.io Startup 首发项目Antmons代币AMS于Aug15th,AM 07:00开始下单,24小时内下单同等对待总共有15,950人下单,下单总价值超过1,000万美金分发系数约为0.001640495298341。根据上线规则AMS项目认购成功,…...
是面试官放水,还是公司实在是太缺人?这都没挂,华为原来这么容易进...
华为是大企业,是不是很难进去啊?” “在华为做软件测试,能得到很好的发展吗? 一进去就有9.5K,其实也没有想的那么难” 直到现在,心情都还是无比激动! 本人211非科班,之前在字节和腾…...
大型购物网站建设/百度资源搜索平台官网
今日凌晨,李笑来在微博表示:“从今往后,李笑来个人不会做任何项目投资(不管是不是区块链,不管是不是早期)。因此,若是你再看到李笑来被站台(之前就长期被站台无数,说99%事…...
网站建设论文读书笔记/竞价交易规则
# Define apscheduler app 下的 __init__.py 文件中, 三个主要函数 转载于:https://www.cnblogs.com/wzbk/p/10396411.html...
wordpress url 静态化/爱站网注册人查询
SQLiteOpenHelper类是Android提供的用于操作SQLite数据库的工具类,该工具类能方便地创建数据库、表,以及管理数据库版本。 常用方法 1、 synchronized SQLiteDatabase getReadableDatabase(); 作用:以读写的方式打开数据库对应的SQLiteDa…...
网站如何做百度权重/图片搜索图片识别
题目 长度为n(n<3e5)的数组,q(q<3e5)次操作,操作分两种, 1. 输入i x(x<1e9),将ai改成x 2. 输入l r k(1<k<n),询问对于在[l,r]内出现的每种数,其在[l,r]内的出现次数是不是均为k的倍数 思…...
江阴市做网站的/如何写好一篇软文
目录写在前面正文同步FIFO回顾异步FIFO设计参考资料交个朋友写在前面一开始是想既然是极简教程,就应该只给出FIFO的概念,没想到还是给出了同步以及异步FIFO的设计,要不然总感觉内容不完整,也好,自己设计的FIFO模块不用…...
创建企业需要什么条件/免费seo推广软件
vector<vector<Point>>::const_iterator itc contours.begin();int cmin 50;while (itc!contours.end()){if (itc->size() < cmin)itc contours.erase(itc);else itc;}...