HR青睐的数据库热门考题——事务

本篇会加入个人的所谓鱼式疯言

❤️❤️❤️鱼式疯言:❤️❤️❤️此疯言非彼疯言

而是理解过并总结出来通俗易懂的大白话,

小编会尽可能的在每个概念后插入鱼式疯言,帮助大家理解的.

🤭🤭🤭可能说的不是那么严谨.但小编初心是能让更多人能接受我们这个概念 !!!

在这里插入图片描述

前言

在上一篇MySQL数据库的文章中,我们提及HR喜欢考的 一个话题 就是:索引

我们讲解了

  • 索引是什么?

索引就是相当于书本的一种特殊的 目录 , 对于 特定的索引列 的查询能够加快 查询的速度

  • 索引的使用特点
  1. 主键unique 外键 会自带索引, 但不能通过 SQL 删除这些索引。

我们也可以通过 SQL 来创建 自身的索引 ,并且删除 自己创建 的索引

  • 索引的不足
  1. 创建索引会占用 额外的内存空间
  1. 索引可能会加快,减慢,数据库的 增删改 操作的速度 。
  • 索引底层的数据结构
  1. 底层是一颗 N叉的B+ 搜索树
  1. B+ 的 特点
  1. B+ 树的 优势

关于这些小伙伴们可以移步 HR眷恋的数据库高频考题之一 —— 索引 文章中。

而本篇文章中

我们核心讲解事务的概念和它最核心的四个特性

目录

  1. 事务的初识

  2. 事务的四大核心特性

  3. 隔离性需要解决的三大问题

  4. 不同隔离级别的特点

一. 事务的初始

在提及事务,和小伙伴们分享个场景

假如 甲同学的数据库下 有 1000
乙同学的数据库下有 500

现在甲同学向乙同学买东西,需要转账 500 给他, 那么我们的数据库是怎么操作的?

就需要先将甲同学的 SQL语句 1数据库先减去 500

然后再执行乙同学的 SQL语句 2数据库加上 500

这样就完成了转账 😁 😁 😁

但是,但是,但是,难免有时候会有意外发生的,当我们执行完 SQL语句 1 的时候,突然程序崩了或者主机断电了 ,SQL 语句 2 就被 终止执行 了 , 那么最终的结果就变成了 甲同学 500乙同学500 这样的问题产生 。

那么这样的问题该怎么解决呢 🤔 🤔 🤔 🤔 。

于是我们就必须要借助事务的特性来解决上述问题 💥 💥 💥 💥

1. 事务的简介

对于上面的问题,我们要解决该问题的方法就是

把上面的 两条语句 都打包成 一个整体 , 要不两条语句都执行,要不两条语句都不执行 。 这样的话我们就 不会 出现上述的问题 。

注意哦 ,这里的 一条语句都不执行不是真不执行 ,而是出现上述这样的问题时, 假如我们只执行了 语句一 , 而执行不了 语句二 , 数据库自身就会把 前面执行过 的所有语句都 还原,撤销回去 ,就好像之前的语句都 没有执行过一样

而像这样我们把所有语句都当成 一个整体 时, 成功执行所有语句 ,或者执行了 一部分语句 ,出现问题时会 自动还原 ,相当于 一条语句都没有执行 的特性 我们就称之为 事务

而我们把这种 自动还原的特性 称之为 回归机制

2. 回滚机制的本质

对于回滚机制 本质

我们知道数据库是一种 客户端-服务器结构 的程序 , 我们 平常的数据 都在存储到 硬盘 上,但还有一个 特殊的机制 ,叫做 日志机制

当我们 执行事务 时,回滚日志 就会 记录 你每一次使用 SQL语句数据的影响 , 而这些 日志记录 都会存储到 某个特定的文件

当我们主机出现程序崩溃 时, 我们回滚日志保留了前面 SQL语句执行 的过程,当下次程序恢复正常时,就会 回撤这些执行 的语句,还原成 原来的样子 .

当主机出现掉电的情况,我们回滚日志也会 保留前面 SQL语句执行的过程以及对数据的各种影响 , 当下次主机重新启动时, 回滚日志就会回退前面 的过程,还原成 执行前的样子

二. 事务的四大核心特性

事务有四大核心特性: 原子性一致性永久性隔离性

1. 原子性

其实,小编在 上一小标题 提及的,把所以的执行的语句都当成 一个整体 ,有可能都执行成功,有可能都执行失败的特性,我们称之为原子性

对于 事务 来说, 上述的特性是最核心也是事务最重要的特性

2. 一致性

事务的 一致性 就是在说,在 执行事务 的过程, 不会在某一点出现和 事务本身 数据不合法 的情况

3. 永久性

执行完一项事务 的过程中,对于 硬盘上修改的数据 是永久修改的,是不会出现 还原回去 的情况的。

4. 隔离性

关于隔离性,小编就就不得不提及和 隔离性相反 的概念: 并发性

什么是并发性???

我们知道数据库是一种 客户端-服务器结构 的程序,当多项事务在不同客户端执行到同一个服务器上时,并且同时 一起执行 , 没有 间隔执行 时,我们就称之为并发执行,而这种特性我们就称为 并发性 。

好比 小编和小伙伴们去餐馆吃饭, 小编点了一个辣椒炒肉,小伙伴们点了麻婆豆腐,红烧肉等…

餐馆的老板就会叫后厨中 多个师傅用多个锅同时炒菜 ,一起做,这样就好比我们事务的 并发执行

这样的执行能 减少时间提高效率

但是缺点就是 不够精细,会影响数据的准确性。

而我们与之相反的就是 隔离性

隔离性 的出现就是为了解决 事务的并发执行可能出现的各种问题。

那么都有 哪些问题 呢?

因为问题比较复杂,小编在下面的章节会详细讲解 💞 💞 💞 💞

小伙伴们请移步下面


内容

三. 隔离性需要解决的三大问题

1. 脏读

<1>. 产生原因

对于这个脏读 的理解,给小伙伴分享个 故事

有一天,有一个小伙伴在小编写文章讲 类和对象 的时候,喵了一眼我当时正在写文章的内容, 上面写了 代码

class Student {
	String name ;
      int age;
}

,于是他就提前知道了我这篇文章要发布的内容,就高兴的离开了。

当我刚要写完这篇类和对象的时候,

为了严谨一点就把代码改成了

class Student {
		String studentName;
		int Studentage;
}

当这个小伙伴看到我发布后的文章时,就惊讶了,怎么内容不一样啊 ,明明我看到的内容是 那个代码 啊,怎么就变成 这个代码 了 😭 😭 😭 😭
读取的结果就 不一样 了 。

像上面这样当 事务A 正在执行的过程中,事务B 读取 事务A 的数据,事务B读取到了那时候 事务A 还没提交 的数据 , 当 事务A提交完成 之后,得到的事务A本身的数据和 事务B读取到的数据 ,就会出现差异,而我们事务B读取到的数据,我们就称为 脏数据 。 而这个过程我们就称之为 脏读 过程。

那么 脏读 该怎么解决呢?

<2>. 解决方案

我们就需要给 加上

什么意思 ? ? ?

就是小编和小伙伴约定好, 当小编在写文章的时候,小伙伴不可以读,如果小伙伴们要学习该内容的话,只有当 小编真正发布本篇文章时 ,才 读取数据

同步到我们事务上说就是当 事务A未提交之前 ,不允许 事务B 进行读取 , 只有当 事务A 完全执行完并且提交之后 , 事务 B 才能进行读取 。 这就是给 上锁 。

鱼式疯言

  1. 这里的脏数据 不是说数据是脏 , 而是我们读到的 数据临时的 , 过时的 不准确的 ,我们才称为 脏数据
  1. 给写上锁 的含义就是 : 把 锁住保护起来,其他事务 不进行任何读 的操作。

2. 不可重复读

<1>. 产生原因

什么叫不可重复读呢?

小编在这里还是分享一个故事给大家理解

上面我们说到,当小编发布完文章之后,发现有些代码有点问题,但当小伙伴们正在读的文章的时候,我正在 修改文章 ,我把 原先文章中代码

class Student {
		String studentName;
		int Studentage;
}

改成了

class Student {
		public  String studentName;
		public  int Studentage;
}

这样小伙伴们读到的数据就从 原先的那段代码 变成了 另外一段代码 ,就会导致数据 读之前读之后 的数据出现 不一致的情况。 像这样的过程我们就叫做 不可重复读

那么在我们的事务中的用语就是: 当 事务A 已经提交了,而 事务B 正在读取 事务A 的数据,此时 事务C 正在修改 事务A 的数据,就会导致 事务B读取 事务A 的数据的前后的 不一致 ,从而造成 不可重复读 的问题。

那么 面对这种问题 我们该怎么解决呢 ? ? ?

<2>. 解决方案

需要解决上述问题的方案就是

给读上锁

所以 我就和 小伙伴们约定 ,当小伙伴们正在读 我的文章 时,我就 不修改文章中的那些代码 ,当小伙伴们 读完之后 ,我再去 修改代码 ,以保证小伙伴们读的前后的 数据不变

那么 回归到事务执行 也一样,当 事务B 正在读 事务A 的数据时, 事务C不要修改 事务A 的数据,当事务B读完数据之后,事务C 才去 修改 事务 A 的内容 。 以此 来保证事务B读数据 前后相一致 , 所以我们把这样的 解决方案 称为 给读上锁

鱼式疯言

给读上锁 的含义就是 : 给读 上把锁保护起来 ,让其他事务在读的过程中,进行不了修改的操作。

3.幻读

<1>. 产生原因

幻读 本质上是我们的不可重复的 一种特殊情况

下面就让小编来细细讲解为什么 幻读 是我们 不可重复读 的一种 特殊情况 吧。

小编还是以故事来开头吧

话说上面我和小伙伴们都约定好,小伙伴读的时候小编 不能修改 , 但是呢?

小编突然在看我自己写的文章的时候,发现我自己写的有个 代码没有补充完整

class Student {
		public  String studentName;
		public  int Studentage;
}

少了一些内容,于是就我在小伙伴们的时候,就加上了一些代码

class Student {
		public  String studentName;
		public  int Studentage;
}


class teacher {
	public String classroom;
	public  String  course; 
}

这样的话,当小伙伴 读的时候 ,就会发现,我们 读的代码 怎么突然多了一个 teacher 的类呢???

是的,当小编在小伙伴们读的时候,就会发现读的内容 前后不一致
而这样的过程就是幻读。

而在我们事务的执行过程中,当一个事务A执行完成之后,事务B 正在读取 事务A 的数据,而此时 事务C 想要在 事务A增加(补充)数据 , 这时就会导致事务B 在读取的过程中造成 读取数据的不一致 。 这样的问题就称为: 事务的幻读

鱼式疯言

所以我们不难发现,和我们上面的 不可重复读 一样的是,事务B 在读取 事务A前后 的数据是 不一致的 。 所以小编才说 幻读 本质上就是 不可重复读 的一种 特殊情况

<2>. 解决方案

对于幻读来说,我们的解决方案就是三个字:

串行化

什么是串行化???

我们还是根据上面的故事来诠释

于是我就和小伙伴又约定,当小伙伴 正在读代码 的时候,我就什么都不做,在那边摸鱼就可以啦,当小伙伴 读完代码 的时候,我就进行 代码的补充 。 这样就可以保证小伙伴们 读代码的前后一致相同 的。

那么当 事务B 正在读已经提交完的 事务A 的时候,事务C 就不能对 事务A 进行 任何操作 ,这样 事务B 在读取 事务A 的前后就能保证数据的一致性 。 而这种解决方案我们就称之为 事务的串行化

鱼式疯言

说了那么多,到底什么事串行化呢?、

串行化的含义:不让多个事务 同时在服务器上执行, 而是让 一个事务执行完之后另一个事务才能继续服务器 上执行。

谈完这三种不同的并发执行产生的问题的 产生原因解决方案

那么我们数据的隔离是以哪些方式来应对这些并发执行可能产生的问题的 🤔 🤔 🤔 🤔

四. 不同隔离级别的特点

对应并发执行事务产生的不同问题, 数据库专门划分了 四种不同的等级 来应对这可能产生的 三个不同的问题

1. 隔离等级一

<1>. 等级一简介

隔离等级一称为 : read uncommitted 读未提交

这个等级是最初始的等级, 并没有解决以上出现的三种问题, 就有可能会并发执行的过程产生 脏读不可重复读幻读 的问题。

<2>. 等级一的特点

并发性 最高, 速度 最快 , 但是隔离性 最低,数据的准确性最差

2. 等级二

<1>. 等级二的简介

隔离等级二称为 : committed 读已提交

这种等级是第二等级,有效的解决了我们事务的并发执行 过程产生的 脏读问题 ,但并没有解决 不可重复读幻读问题

<2>. 等级二的特点

读已提交的特点就是 :

并发程度 较高 , 速度 较快 , 隔离程度 较低 , 准确性 较低

3. 等级三

<1>. 等级三简介

隔离等级三 : repeatable read 可重复读

这个等级的主要是解决了我们 并发过程脏读不可重复读 的问题, 但是并没有解决我们的 幻读 的问题 。

<2>. 等级三特点

并发程度 较低 , 速度 较快 ,隔离程度就 较高 , 准确性 较好

鱼式疯言

其实我们 MySQL 中就是用的这 一套的 隔离等级

4. 等级四

<1>. 等级四的简介

等级四 : Serializable 串行化

隔离的最后的一个等级 串行化,成功的解决了事务 并发执行 过程中会的出现的 脏读 不可重复读幻读

<2>. 等级四的特点

并发程度 最低,速度 最慢,隔离性 最高 , 准确性也是 最好的

鱼式疯言

  1. 以上小编就可以总结出 :

并发程度和隔离程度是效果是 互斥相反的, 并发程度 越高 ,隔离程度 越低 。 同时并发程度和我们执行速度是 相同的 ,隔离程度和准确程度是 相同的 , 并发程度 越高 ,执行速度 越快

  1. 对于这四种不同的隔离等级

我们得根据不同的使用场景来确定我们是需要 并发程度高,速度快 的隔离等级, 还是需要隔离程度高,准确性高的隔离等级 。

好比我们 银行的事务执行 ,就需要像隔离等级四这个隔离等级高,准确性好的。

而像我们平常的抖音,快手等短视频的 几万几十万的点击率 就需要并发 程度高,速度快

总结

  • 事务的初识 : 我们介绍了事务的最根本的特性: 原子性是把 多个SQL语句 包装成一个整体,要不都执行,要不都不执行。

    从而理解事务本身就是以原子性执行的,

  • 事务的四大核心特性 : 有原子性,一致性,永久性,和隔离性。

  • 隔离性需要解决的三大问题: 事务并发执行过程中有可能会产生: 脏读,不可重复读,幻读。

  • 不同隔离级别的特点 : 数据库构造了四种不同的等级来应对以上三种问题: 读未提交,读已提交, 重复读, 串行化 。

如果觉得小编写的还不错的咱可支持 三连 下 (定有回访哦) , 不妥当的咱请评论区 指正

希望我的文章能给各位宝子们带来哪怕一点点的收获就是 小编创作 的最大 动力 💖 💖 💖

在这里插入图片描述

  • 115
    点赞
  • 86
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 72
    评论
好的,以下是一道可能的MySQL数据库期末考试题: 考试题目: 一个学生选课的数据库包含两张表:学生表(student)和选课表(course_student)。学生表包含学生的id、姓名、性别和出生日期等信息;选课表包含选课记录的id、学生id和课程id等信息。请根据以下要求,编写SQL语句查询对应的结果。 1. 查询每个学生选了多少门课程,并按照选课门数从多到少排序。 2. 查询每个学生所选的课程名称和任课教师,并按照学生id升序排序。 3. 查询选了“数学”课程的学生的姓名和选课门数,并按照选课门数从多到少排序。 4. 查询选了“数学”课程但未选“英语”课程的学生的姓名和选课门数,并按照选课门数从多到少排序。 5. 查询选课门数排名前三的学生的id、姓名和选课门数。 考试答案: 1. ```sql SELECT cs.student_id, COUNT(*) AS course_count FROM course_student AS cs GROUP BY cs.student_id ORDER BY course_count DESC; ``` 2. ```sql SELECT s.id, s.name, c.name AS course_name, c.teacher FROM student AS s JOIN course_student AS cs ON s.id = cs.student_id JOIN course AS c ON cs.course_id = c.id ORDER BY s.id ASC; ``` 3. ```sql SELECT s.name, COUNT(*) AS course_count FROM student AS s JOIN course_student AS cs ON s.id = cs.student_id JOIN course AS c ON cs.course_id = c.id WHERE c.name = '数学' GROUP BY s.id ORDER BY course_count DESC; ``` 4. ```sql SELECT s.name, COUNT(*) AS course_count FROM student AS s JOIN course_student AS cs1 ON s.id = cs1.student_id JOIN course AS c1 ON cs1.course_id = c1.id LEFT JOIN course_student AS cs2 ON s.id = cs2.student_id AND cs2.course_id = (SELECT id FROM course WHERE name = '英语') WHERE c1.name = '数学' AND cs2.course_id IS NULL GROUP BY s.id ORDER BY course_count DESC; ``` 5. ```sql SELECT s.id, s.name, COUNT(*) AS course_count FROM student AS s JOIN course_student AS cs ON s.id = cs.student_id GROUP BY s.id ORDER BY course_count DESC LIMIT 3; ``` 希望以上MySQL数据库期末考试题和答案能够对您有所帮助。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 72
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

邂逅岁月

感谢干爹的超能力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值