大厂面试官问我:MySQL宕机重启了,怎么知道哪些事务是需要回滚的哪些是需要提交的?【后端八股文九:Mysql事务八股文合集】

本文为【Mysql事务八股文合集】初版,后续还会进行优化更新,欢迎大家关注交流~

大家第一眼看到这个标题,不知道心中是否有答案了?在面试当中,面试官经常对项目亮点进行深挖,来考察你对这个项目亮点的理解以及思考!这个时候,你如果可以回答出面试官的问题,甚至是主动说出自己的思考,那在面试中是大大加分的~

 

什么是事务?

事务是逻辑的一组操作,要么都执行,要么都不执行

# 开启一个事务
START TRANSACTION;
# 多条 SQL 语句
SQL1,SQL2...
## 提交事务
COMMIT;

请你描述下事务的特性?

(ACID)
(一原吃哥)
原子性A   最小的执行单位,不允许分割      要么全部完成,要么完全不起作用
一致性C 前后,数据库从一个一致性状态转换到另一个一致性
隔离性I   并发    不被其他事务所干扰   事务独立
持久性D  提交后   改变是持久

怎么实现

原子性(redo 和 undo 日志)
在执行事务期间,将修改的数据写入 redo 日志,并在事务提交前将其持久化到磁盘,确保事务的持久性。如果事务发生故障或回滚操作,可以使用 undo 日志来撤销事务的修改,使数据回滚到事务开始之前的状态。
隔离性(锁机制和多版本并发控制)
持久性(redo 日志)

innodb的默认隔离级别以及使用的技术

默认隔离级别是可重复读RR,但是用到了MVCC的快照读当前读技术以及next-key锁,所以可以解决幻读问题。对标SQL标准的可串行化。

对事务隔离级别的理解

(未提交读,提交读,可重复读,串行化)
READ_UNCOMMITTED(未提交读)
最低的隔离级别,允许读取尚未提交的数据变更,可能会导致脏读、幻读或不可以重复读

解决了更新丢失,但还是可能会出现脏读

READ_COMMITTED(提交读)
允许读取并发事务已经提交的数据,可以阻止脏读,但是幻读或不可重复读仍有可能发生
(Oracle的隔离级别)
解决了更新丢失和脏读问题

REPEATABLE_READ(可重复读)
在一个事务内,最开始读到的数据和事务结束前的任意时刻读到的同一批数据都是一致的
通常针对数据更新(UPDATE)操作。
解决了更新丢失、脏读、不可重复读、但是还会出现幻读

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

只有串行化的隔离级别解决了全部这 3 个问题,其他的 3 个隔离级别都有缺陷。

【扩展:脏读、幻读或不可重复读】
【扩展:每种隔离级别分别解决了什么问题】
【扩展:实现原理】

实现原理

读未提交,采取的是"不加锁读"原理。

  • 事务读不加锁,不阻塞其他事务的读和写
  • 事务写阻塞其他事务写,但不阻塞其他事务读;

读已提交
锁定读
事务在读取数据时会对数据进行短暂的排他锁定,确保其他事务不能修改数据。

实现可重复读,MySQL 采用了 MVVC (多版本并发控制) 的方式。
每个事务在读取数据时会创建一个数据快照,并使用保存的快照来获取一致的结果。

串行化

  • 所有SELECT语句会隐式转化为SELECT … FOR SHARE,即加共享锁
  • 读加共享锁,写加排他锁,读写互斥。如果有未提交的事务正在修改某些行,所有select这些行的语句都会阻塞。

可重复读怎么实现的

MVCC(多版本并发控制): MySQL使用MVCC来实现可重复读。在MVCC中,每行数据都会有一个创建版本号(也称为事务ID或时间戳)和一个过期版本号。当一个事务开始时,它会获得一个唯一的事务ID。在事务执行期间,它只能看到创建版本号小于或等于自己事务ID的数据。这确保了事务只会读取到它开始之前已经提交的数据,而不会读取到正在进行中的其他事务的数据。

读已提交和可重复读中 readView 有什么区别

在读已提交中,每个查询都会创建一个新的readView,读取最新的已提交事务的数据。在可重复读中,一个事务的整个生命周期内只创建一个readView,始终读取相同的版本,以确保事务的一致性视图。

如何解决脏读

通过排他锁和共享锁完成。事务A加排他锁进行修改,事务结束前不会释放锁。事务B想要读取,要共享锁,但是由于有了排他锁,因此共享锁阻塞。等事务A结束,才能读取得到。

既然innodb的可重复读已经解决了幻读问题,那么和串行化的实现区别是什么

可重复读通过next-key锁解决了当前读下的幻读问题。而串行化是通过加表锁来解决的。

解释下什么叫脏读、不可重复读和幻读?

(并发事务带来的)
脏读
(读取未提交数据)
(一个事务正在访问数据并进行了修改,而这种修改还未提交,另外一个事务也访问到了这个数据,使用了这个还未修改的数据)
(读未提交的数据)

不可重复读
(前后多次读取,数据内容不一致)
在一个事务内,多次读同一数据,另一个事务访问修改,导致数据读取结果不一样
(多次结果不同,查询期间另一个事务修改数据)

幻读
(前后多次读取,数据总量不一致)
(类似不可重复读,在发生一个事务1读取几行数据,接着另一个事务插入了一些数据,导致第一个事务1多一些原本不存在的,像是幻觉,所以叫幻读)

丢失修改
一个事务读取数据,另一个事务也访问,都修改了数据,但丢失了事务1修改的数据
(两个同时修改)

不可重复读和脏读的区别
脏读是读取另一个事务未提交的脏数据
不可重复读是读取了前一事务提交的数据

可重复读(RR)怎么解决幻读

在可重复读的情况下,MySQL引入MVCC,但MVCC并没有真正解决了幻读
可重复读开启了间隙锁,而间隙锁解决了幻读。

所以在可重复读下用间隙锁或next key锁才可以防止幻读。不使用间隙锁是无法解决幻读的。其实在读提交下检测唯一索引的唯一性也会开启间隙锁。

next-key locks由record locks(索引加锁) 和 gap locks(间隙锁,每次锁住的不光是需要使用的数据,还会锁住这些数据附近的数据)

解决方案

不可重复读是读取了其他事务更改的数据,针对update操作
解决:
使用行级锁,锁定该行

幻读是读取了其他事务新增的数据,针对insert和delete操作
解决:
(1)使用表级锁,锁定整张表
(2)间隙锁是innodb中行锁的一种, 但是这种锁锁住的却不止一行数据,他锁住的是多行,是一个数据范围。间隙锁的主要作用是为了防止出现幻读,但是它会把锁定范围扩大,

(3)MVCC也可以

Mysql默认的隔离级别

MySQL默认采用的 REPEATABLE_READ隔离级别。(可重复读)

Oracle 默认采用的 READ_COMMITTED 隔离级别。(提交读)

谈谈对MVCC的了解

(相当于给我们的MySQL数据库拍个“快照”)
(版本号,读只读事务前的快照,并发读写性能高,解决脏读、幻读、不可重复读,但不能解决更新丢失问题)
用于实现读已提交和可重复读取隔离级别。

在数据库中维护多个版本的数据来支持并发事务的同时读取和写入操作

MVCC的核心思想是每个事务在读取数据时看到的是一致性的快照,而不会受到其他并发事务的修改的影响。它基于以下两个基本概念:

  1. 版本号:每个数据项都有一个与之关联的版本号,用于标识数据的版本。版本号可以是递增的序列号、时间戳或其他唯一标识。
  2. 快照读取:事务在读取数据时,会根据自身的事务时间戳(或其他标识)选择合适的版本进行读取。只有那些在事务开始之前创建的、版本号小于等于事务时间戳的数据才能被读取,而在事务期间创建或修改的数据对该事务不可见。

多版本并发控制(MVCC)
一种用来解决读-写冲突的无锁并发控制,也就是为事务分配单向增长的时间戳,为每个修改保存一个版本,版本与事务时间戳关联,

读操作只读该事务开始前的数据库的快照

解决以下问题:

  1. 在并发读写数据库时,可以做到在读操作时不用阻塞写操作写操作也不用阻塞读操作提高了数据库并发读写的性能
  2. 同时还可以解决脏读,幻读,不可重复读等事务隔离问题,但不能解决更新丢失问题

MVCC的优势在于读操作不会阻塞写操作,也不会读取到脏数据。每个事务读取的是一致性的数据快照,因此可以实现高并发性和较好的隔离性。

实现

版本号

它的实现原理主要是依赖记录中的 3个隐式字段,undo日志 ,Read View 来实现的

当前读和快照读

select 快照读
快照读是读取事务开始前的数据样子,不受其他事务修改的影响,但可能遇到幻读问题。
(像不加锁的select操作就是快照读,即不加锁的非阻塞读)

会对数据修改的操作(update,insert,delete)都是采用当前读的模式
当前读是读取最新的数据,会反映其他事务的修改,确保数据一致性,但可能会导致锁竞争和性能开销。
(select lock in share mode(共享锁), select for update ; update, insert ,delete(排他锁)这些操作都是一种当前读)

说白了MVCC就是为了实现读-写冲突不加锁,而这个读指的就是快照读, 而非当前读,当前读实际上是一种加锁的操作,是悲观锁的实现

RR和RC下MVCC有什么区别

"RR" 代表 "Repeatable Read"(可重复读)
"RC" 代表 "Read Committed"(已提交读)

  • 在RR中,只要事务开始之后读了一次数据,那么就会生产快照,只会读都会直接读这个快照,因此不论别的事务怎么改动,都是可重复读的。
  • 而RC中,每次读都会生成一次快照,所以不可重复读

什么情况下mysql事务会失效?

  • DDL语句(CREATE TABLE, ALTER TABLE等)会隐式提交事务
  • LOCK TABLE语句会隐式提交事务
  • 用户执行COMMIT或ROLLBACK时
  • 发生致命错误(如服务器崩溃)时
  • 超时(事务执行时间太长)时

能否用mysql实现分布式锁

可以。MySQL提供了基于表的分布式锁实现方式,即使用一个专门的表来实现分布式锁。具体做法是:

  • 创建一个专门的表用于锁定
  • 事务开始时尝试获取锁,获取成功则执行业务逻辑,最后释放锁
  • 获取锁失败则重试或放弃

查询语句会开启事务吗,update语句会吗,为什么

  • 查询语句(SELECT)一般不会开启事务,除非显式地开启事务
  • Update语句会隐式地开启事务,因为它会修改数据,需要遵循ACID原则
  • 事务的开启和提交/回滚与DML语句(INSERT/UPDATE/DELETE)有关,而非SELECT

mysql 数据库事务回滚如何实现?

MySQL使用UNDO日志来实现事务回滚。UNDO日志记录了事务执行过程中的所有修改操作,当需要回滚时,MySQL会按照UNDO日志的反向操作来撤销之前的修改。

MySQL宕机重启了,怎么知道哪些事务是需要回滚的哪些是需要提交的?

MySQL宕机重启后如何知道哪些事务需要回滚:
MySQL会依赖于REDO日志和undo日志来进行恢复。

    • REDO日志记录了已提交事务的修改,用于恢复已提交的数据
    • UNDO日志记录了未提交事务的修改,用于回滚未提交的事务
      MySQL在重启时会扫描这两个日志,根据日志内容来判断哪些事务需要提交哪些需要回滚。

mysql事务实现的原理

(从redo log、bin log来思考)

  • REDO log用于记录数据页的修改,确保数据库在crash后可以恢复到最后一次提交的状态
  • BIN log用于记录所有数据库的变更操作,用于主从复制和备份恢复

mysql事务的死锁

当两个或多个事务在同时访问相同的数据资源且互相等待对方释放资源时,就会产生死锁。MySQL会检测到死锁的发生,并选择牺牲其中一个事务,让其他事务可以顺利完成。被牺牲的事务会收到"Deadlock found when trying to get lock; try restarting transaction"的错误。

  后期新的八股文合集文章会继续分享,感兴趣的小伙伴可以点个关注~

 更多精彩内容以及免费资料请关注公众号:绝命Coding

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/777162.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

2024/7/6 英语每日一段

More than half of late-teens are specifically calling for more youth work that offers “fun”, with older teenagers particularly hankering for more jollity, according to a study carried out by the National Youth Agency. One in 10 said they have zero option…

vite+vue3整合less教程

1、安装依赖 pnpm install -D less less-loader2、定义全局css变量文件 src/assets/css/global.less :root {--public_background_font_Color: red;--publicHouver_background_Color: #fff;--header_background_Color: #fff;--menu_background: #fff; }3、引入less src/main.…

罗剑锋的C++实战笔记学习(二):容器、算法库、多线程

4、容器 1)、容器的通用特性 所有容器都具有的一个基本特性:它保存元素采用的是值(value)语义,也就是说,容器里存储的是元素的拷贝、副本,而不是引用 容器操作元素的很大一块成本就是值的拷贝…

重大更新来袭!!《植物大战僵尸杂交版V2.1+修改器+融合版》

大家好!每个软件更新总是令人兴奋不已。前段时间介绍的《植物大战僵尸》系列以其独特的策略玩法和丰富的植物角色,赢得了很多玩家的喜爱。而在今天,这款经典游戏全网最新版本——《植物大战僵尸:杂交版V2.1》正式推出,…

【Mindspore进阶】实战ResNet50图像分类

ResNet50图像分类 图像分类是最基础的计算机视觉应用,属于有监督学习类别,如给定一张图像(猫、狗、飞机、汽车等等),判断图像所属的类别。本章将介绍使用ResNet50网络对CIFAR-10数据集进行分类。 ResNet网络介绍 ResNet50网络是2015年由微…

vue require引入静态文件报错

如果是通过向后端发送请求,动态的获取对应的文件数据流很容易做到文件的显示和加载。现在研究,一些不存放在后端而直接存放在vue前端项目中的静态媒体文件如何加载。 通常情况下,vue项目的图片jpg,png等都可以直接在/ass…

量化机器人:金融市场的智能助手

引言 想象一下,在繁忙的金融市场中,有一位不知疲倦、冷静客观的“超级交易员”,它能够迅速分析海量数据,精准捕捉交易机会,并自动完成买卖操作。这位“超级交易员”不是人类,而是我们今天要聊的主角——量…

Qt5.9.9 关于界面拖动导致QModbusRTU(QModbusTCP没有测试过)离线的问题

问题锁定 参考网友的思路: Qt5.9 Modbus request timeout 0x5异常解决 网友认为是Qt的bug, 我也认同;网友认为可以更新模块, 我也认同, 我也编译了Qt5.15.0的code并成功安装到Qt5.9.9中进行使用,界面拖…

从CPU的视角看C++的构造函数和this指针

从汇编角度,清晰的去看构造函数和this指针到底是个什么东西呢?也许可以解决你的一点小疑问 首先写一个很简单的代码demo: class A{ public:int a;A(){;}void seta(int _a){a_a;}A* getA(){return this;} };int fun1(int px){return px; }in…

全新桌面编辑器

目录 前言 一、链接 ONLYOFFICE 8.1版本 官网下载链接: ONLYOFFICE 在线工具: 下载版本推荐: 二、使用体验 1. 界面设计: 2. 文档编辑功能: 3. 电子表格功能: 4. 演示文稿功能: 5.PDF编…

python-开关灯(赛氪OJ)

[题目描述] 假设有 N 盏灯(N 为不大于 5000 的正整数),从 1 到到 N 按顺序依次编号,初始时全部处于开启状态;第一个人( 1 号)将灯全部关闭,第二个人( 2 号)将…

nginx修改网站默认根目录及发布(linux、centos、ubuntu)openEuler软件源repo站点

目录 安装nginx配置nginx其它权限配置 安装nginx dnf install -y nginx配置nginx whereis nginxcd /etc/nginx llcd conf.d touch vhost.conf vim vhost.conf 命令模式下输入:set nu或:set number可以显示行号 复制如下内容: server {listen 80;server_name…

基于java+springboot+vue实现的流浪动物管理系统(文末源码+Lw)277

摘 要 在如今社会上,关于信息上面的处理,没有任何一个企业或者个人会忽视,如何让信息急速传递,并且归档储存查询,采用之前的纸张记录模式已经不符合当前使用要求了。所以,对流浪动物信息管理的提升&…

玩转Easysearch语法

Elasticsearch 是一个基于Apache Lucene的开源分布式搜索和分析引擎,广泛应用于全文搜索、结构化搜索、分析等多种场景。 Easysearch 作为Elasticsearch 的国产化替代方案,不仅保持了与原生Elasticsearch 的高度兼容性,还在功能、性能、稳定性…

Spring框架Mvc(2)

1.传递数组 代码示例 结果 2.集合参数存储并进行存储类似集合类 代码示例 postman进行测试 ,测试结果 3.用Json来对其进行数据的传递 (1)Json是一个经常使用的用来表示对象的字符串 (2)Json字符串在字符串和对象…

Mysql数据库索引、事务相关知识

索引 索引是一种特殊的文件,包含着对数据表里所有记录的引用指针。可以对表中的一列或多列创建索引, 并指定索引的类型,各类索引有各自的数据结构实现 查看索引 show index from 表名;创建索引对于非主键、非唯一约束、非外键的字段&#…

JAVA ArrayList应用案例

一案例要求&#xff1a; 二代码&#xff1a; package 重修;import java.util.ArrayList; import java.util.Random; import java.util.Scanner;public class first {public static void main(String[] args) {ArrayList<String>arrayListnew ArrayList<>();array…

ctfshow-web入门-文件包含(web87)巧用 php://filter 流绕过死亡函数的三种方法

目录 方法1&#xff1a;php://filter 流的 base64-decode 方法 方法2&#xff1a;通过 rot13 编码实现绕过 方法3&#xff1a;通过 strip_tags 函数去除 XML 标签 除了替换&#xff0c;新增 file_put_contents 函数&#xff0c;将会往 $file 里写入 <?php die(大佬别秀了…

微软与OpenAI/谷歌与三星的AI交易受欧盟重点关注

近日&#xff0c;欧盟委员会主管竞争事务的副主席玛格丽特维斯塔格(Margrethe Vestager)在一次演讲中透露&#xff0c;欧盟反垄断监管机构将就微软与OpenAI的合作&#xff0c;以及谷歌与三星达成的AI协议寻求更多第三方意见。这意味着微软与 OpenAI、谷歌与三星的 AI 交易及合作…

MySQL中的DDL语句

第一题 输入密码登录mysql&#xff0c;创建数据库zoo&#xff0c;转换到zoo数据库&#xff0c; mysql> create database zoo character set gbk; mysql> use zoo查看创建数据库zoo信息 mysql> show create database zoo;删除数据库zoo mysql> drop database zo…