【每日八股】复习 MySQL Day1:事务

news2025/4/21 20:23:57

文章目录

  • 复习 MySQL Day1:事务
    • MySQL 事务的四大特性?
    • 并发事务会出现什么问题?
    • MySQL 事务的隔离级别?
    • 不同事务隔离级别下会发生什么问题?
    • MVCC 的实现原理?
      • 核心数据结构
      • 版本链构建示例
      • 可见性判断算法
      • MVCC 可见性判断总结
    • 幻读如何解决?
    • 读已提交隔离级别如何实现?

复习 MySQL Day1:事务

在这里插入图片描述

MySQL 事务的四大特性?

  • 原子性:事务当中的若干条数据库操作要么全部成功,要么全部失败;
  • 一致性:数据库总是从一个一致性的状态迁移到另一个一致性的状态;
  • 隔离性:事务提交之前,对数据库做出的更改对其他事务不可见;
  • 持久性:事务提交之后就会被持久化到磁盘当中。

并发事务会出现什么问题?

指的主要是由 MySQL 隔离级别的不同带来的若干问题。

  • 脏读:事务还未提交,其所做的修改就已经可以被其他事务所读取了;
  • 不可重复读:事务开始时读取的数据与事务执行过程中读取到的数据不同;
  • 幻读:通常发生在区间查询的场景下,指的是在一个事务执行期间内,上一次范围查询读取到的数据与本次范围查询读取到的数据不一致,其发生的原因可能是在事务执行期间有其他事务向第一次查询的数据区间当中插入了新的数据。

MySQL 事务的隔离级别?

  • 读未提交:事务还未提交,其他事务就可看到其所做的更改,隔离级别最低;
  • 读已提交:事务提交之后,其所做的更改才能够被其他事务所看到。在读已提交隔离级别下,当前事务可以看到其他事务执行完成后所做的修改;
  • 可重复读:MySQL InnoDB 数据引擎的默认隔离级别,指的是从事务开始到事务结束期间,读取到的数据都是一致的;
  • 串行化:对记录加上读写锁,在多个事务进行读写的过程中,如果发生了锁冲突,那么当前事务必须等上一个事务读写完成方可进行读写。串行化不存在并发事务的问题,但它的并发性能最差。

不同事务隔离级别下会发生什么问题?

  • 读未提交:脏读、不可重复读、幻读;
  • 读已提交:不可重复读、幻读;
  • 可重复读:幻读;
  • 串行化:不存在并发事务的问题;

MVCC 的实现原理?

MVCC 是数据库实现并发控制的关键技术,InnoDB 数据引擎通过 MVCC 实现读操作的并发,极大提高了数据库的并发性能。

核心数据结构

隐藏字段
InnoDB 为每行记录添加了以下隐藏字段:

  • DB_TRX_ID:记录创建或最后一次修改该行记录的事务 ID;
  • DB_ROLL_PTR:回滚指针,指向 undo log 记录;
  • DB_ROW_ID:隐含的自增行 ID;
  • DELETE BIT:记录该行是否删除。

Undo Log(回滚日志)

  • 存储行记录的历史版本;
  • 组成版本链,通过 DB_ROLL_PTR 指针连接;
  • 用于事务回滚与 MVCC 读取。

Read View(读视图)

  • m_ids:生成 Read View 时活跃的事务 ID 列表;
  • min_trx_id:m_ids 中的最小事务 ID;
  • max_trx_id:m_ids 中的最大事务 ID;
  • create_trx_id:创建该 Read View 的事务 ID。

版本链构建示例

  1. 每次更新操作都会在 undo log 记录旧数据版本;
  2. 通过 DB_ROLL_PTR 指针形成单向链表;
  3. 链表头是最新版本,尾部是最旧版本。

可见性判断算法

比较 DB_TRX_ID 与 creator_trx_id
如果相等,说明当前记录是该事务自身修改的事务,对当前事务可见。

检查 DB_TRX_ID < min_trx_id
说明这条记录在当前 Read View 生成之前已经提交,对当前事务可见。

检查 DB_TRX_ID >= max_trx_id
说明这条记录是在 Read View 生成之后创建的,对当前事务不可见。

检查 DB_TRX_ID 是否在 m_ids 事务活跃列表当中

  • 存在:生成 Read View 时当前记录仍活跃,对当前事务不可见;
  • 不存在:最后一次修改该条记录的事务已提交,对当前事务可见;

MVCC 可见性判断总结

总的来说,针对基于 MVCC 的事务可见性判断,关键的字段包括以下几个:

  • 对于记录,每一条记录都有一个隐式的 DB_TRX_ID 字段,用于记录最后一个修改这条记录的事务 ID;
  • 对于 SELECT 操作生成的 Read View,其隐式包含以下几个字段:
    1)m_ids:Read View 生成时活跃的事务 ID 列表;
    2)min_trx_id:m_ids 中最小的事务 ID;
    3)max_trx_id:m_ids 中最大的事务 ID;
    4)create_trx_id:创建这个 Read View 的事务 ID。

可见性判断的算法流程如下:

  1. 首先对比记录的 DB_TRX_ID 和 creator_trx_id,相等则代表该记录最后一次由当前视图修改,对该事务可见;
  2. 之后再比对 DB_TRX_ID 和 min_trx_id 以及 max_trx_id 的大小,如果小于 min_trx_id,说明修改该记录的事务在生成 Read View 时已提交,对当前事务可见;如果大于 max_trx_id,说明修改该记录的事务在当前事务之后创建,其所做的修改对当前事务不可见,通过 DB_ROLL_PTR 找到该记录的上一个版本。
  3. 最后查看 DB_TRX_ID 是否在 m_ids 当中,如果在,说明修改这条记录的事务在活跃列表当中,该记录的当前版本对当前事务不可见;否则说明修改该记录的事务已经提交,这条记录对当前事务可见。

幻读如何解决?

通过快照读(一致性非锁定读)
对于普通的 SELECT 查询语句,InnoDB 使用 MVCC 提供一致性视图,避免看到其他事务插入的数据。

使用间隙锁(Gap Lock)和临键锁(Next-Key Lock)
InnoDB 在可重复读隔离级别下通过以下方式防止幻读:

  • 间隙锁(Gap Lock):锁定索引记录之间的间隙;
  • 临键锁(Next-Key Lock):临键锁是记录锁(行锁)+ 间隙锁的组合,锁定记录及其前面的间隙。

一个基于间隙锁 + 临键锁防止幻读的例子如下:

-- 事务1
BEGIN;
SELECT * FROM users WHERE age > 20 FOR UPDATE; -- 锁定age>20的所有记录和间隙
-- ⬆️ 显式地使用区间锁锁定一个范围, 避免在范围内有新记录插入
-- 此时事务2尝试插入age>20的记录会被阻塞
INSERT INTO users(name, age) VALUES('new_user', 25); -- 阻塞

总结
使用「MVCC 版本控制」或「间隙锁 + 临键锁」这两种方式可以避免幻读的问题。

读已提交隔离级别如何实现?

在读已提交隔离级别下,每次执行 SELECT 语句都会创建一个 Read View。创建 Read View 时已经提交的事务所做的修改对当前事务是可见的(会导致不可重复读问题),但未提交以及当前事务之后的事务所做的修改不可见。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

外接键盘与笔记本命令键键位不同解决方案(MacOS)

文章目录 修改键位第一步&#xff1a;打开设置第二步&#xff1a;进入键盘快捷键第三步&#xff1a;修改修饰键设置第四步&#xff1a;调整键位第五步&#xff1a;保存设置tips ikbc c87键盘win键盘没反应的解决亲测的方法这是百度的答案标题常规组合键尝试‌&#xff1a;型号差…

kotlin知识体系(五) :Android 协程全解析,从作用域到异常处理的全面指南

1. 什么是协程 协程(Coroutine)是轻量级的线程&#xff0c;支持挂起和恢复&#xff0c;从而避免阻塞线程。 2. 协程的优势 协程通过结构化并发和简洁的语法&#xff0c;显著提升了异步编程的效率与代码质量。 2.1 资源占用低&#xff08;一个线程可运行多个协程&#xff09;…

vscode stm32 variable uint32_t is not a type name 问题修复

问题 在使用vscodekeil开发stm32程序时&#xff0c;发现有时候vscode的自动补全功能失效&#xff0c;且problem窗口一直在报错。variable “uint32_t” is not a type name uint32_t 定义位置 uint32_t 实际是在D:/Keil_v5/ARM/ARMCC/include/stdint.h中定义的。将D:/Keil_v5…

Formality:Bug记录

相关阅读 Formalityhttps://blog.csdn.net/weixin_45791458/category_12841971.html?spm1001.2014.3001.5482 本文记录博主在使用Synopsys的形式验证工具Formality中遇到的一个Bug。 Bug复现 情况一 // 例1 module dff (input clk, input d_in, output d_out …

【java+Mysql】学生信息管理系统

学生信息管理系统是一种用于管理学生信息的软件系统&#xff0c;旨在提高学校管理效率和服务质量。本课程设计报告旨在介绍设计和实现学生信息管理系统的过程。报告首先分析了系统的需求&#xff0c;包括学生基本信息管理、成绩管理等功能。接着介绍了系统的设计方案&#xff0…

小白从0学习网站搭建的关键事项和避坑指南(2)

以下是针对小白从零学习网站搭建的 进阶注意事项和避坑指南&#xff08;第二期&#xff09;&#xff0c;覆盖开发中的高阶技巧、常见陷阱及解决方案&#xff0c;帮助你在实战中提升效率和质量&#xff1a; 一、进阶技术选型避坑 1. 前端框架选择 误区&#xff1a;盲目追求最新…

Windows 10 上安装 Spring Boot CLI详细步骤

在 Windows 10 上安装 Spring Boot CLI 可以通过以下几种方式完成。以下是详细的步骤说明&#xff1a; 1. 手动安装&#xff08;推荐&#xff09; 步骤 1&#xff1a;下载 Spring Boot CLI 访问 Spring Boot CLI 官方发布页面。下载最新版本的 .zip 文件&#xff08;例如 sp…

vue2技术练习-开发了一个宠物相关的前端静态商城网站-宠物商城网站

为了尽快学习掌握相关的前端技术&#xff0c;最近又实用 vue2做了一个宠物行业的前端静态网站商城。还是先给大家看一下相关的网站效果&#xff1a; 所以大家如果想快速的学习或者掌握一门编程语言&#xff0c;最好的方案就是通过学习了基础编程知识后&#xff0c;就开始利用…

嵌入式学习——远程终端登录和桌面访问

目录 通过桥接模式连接虚拟机和Windows系统 1、桥接模式 2、虚拟机和Windows连接&#xff08;1&#xff09; 3、虚拟机和Windows连接&#xff08;2&#xff09; 在Linux虚拟机中创建新用户 Windows系统环境下对Linux系统虚拟机操作 远程登录虚拟机&#xff08;1&#xff…

如何新建一个空分支(不继承 master 或任何提交)

一、需求分析&#xff1a; 在 Git 中&#xff0c;我们通常通过 git branch 来新建分支&#xff0c;这些分支默认都会继承当前所在分支的提交记录。但有时候我们希望新建一个“完全干净”的分支 —— 没有任何提交&#xff0c;不继承 master 或任何已有内容&#xff0c;这该怎么…

Qt编写推流程序/支持webrtc265/从此不用再转码/打开新世界的大门

一、前言 在推流领域&#xff0c;尤其是监控行业&#xff0c;现在主流设备基本上都是265格式的视频流&#xff0c;想要在网页上直接显示监控流&#xff0c;之前的方案是&#xff0c;要么转成hls&#xff0c;要么魔改支持265格式的flv&#xff0c;要么265转成264&#xff0c;如…

[第十六届蓝桥杯 JavaB 组] 真题 + 经验分享

A&#xff1a;逃离高塔(AC) 这题就是简单的签到题&#xff0c;按照题意枚举即可。需要注意的是不要忘记用long&#xff0c;用int的话会爆。 &#x1f4d6; 代码示例&#xff1a; import java.io.*; import java.util.*; public class Main {public static PrintWriter pr ne…

深⼊理解 JVM 执⾏引擎

深⼊理解 JVM 执⾏引擎 其中前端编译是在 JVM 虚拟机之外执⾏&#xff0c;所以与 JVM 虚拟机没有太⼤的关系。任何编程语⾔&#xff0c;只要能够编译出 满⾜ JVM 规范的 Class ⽂件&#xff0c;就可以提交到 JVM 虚拟机执⾏。⾄于编译的过程&#xff0c;如果你不是想要专⻔去研…

iwebsec靶场 文件包含关卡通关笔记11-ssh日志文件包含

目录 日志包含 1.构造恶意ssh登录命令 2.配置ssh日志开启 &#xff08;1&#xff09;配置sshd &#xff08;2&#xff09;配置rsyslog &#xff08;3&#xff09;重启服务 3.写入webshell木马 4.获取php信息渗透 5.蚁剑连接 日志包含 1.构造恶意ssh登录命令 ssh服务…

kafka菜鸟教程

一、kafka原理 1、kafka是一个高性能的消息队列系统&#xff0c;能够处理大规模的数据流&#xff0c;并提供低延迟的数据传输&#xff0c;它能够以每秒数十万条消息的速度进行读写操作。 二、kafka优点 1、服务解耦 &#xff08;1&#xff09;提高系统的可维护性‌ 通过服务…

应用镜像是什么?轻量应用服务器的镜像大全

应用镜像是轻量应用服务器专属的&#xff0c;镜像就是轻量应用服务器的装机盘&#xff0c;应用镜像在原有的纯净版操作系统上集成了应用程序&#xff0c;例如WordPress应用镜像、宝塔面板应用镜像、WooCommerce等应用&#xff0c;阿里云服务器网aliyunfuwuqi.com整理什么是轻量…

深入理解分布式缓存 以及Redis 实现缓存更新通知方案

一、分布式缓存简介 1. 什么是分布式缓存 分布式缓存&#xff1a;指将应用系统和缓存组件进行分离的缓存机制&#xff0c;这样多个应用系统就可以共享一套缓存数据了&#xff0c;它的特点是共享缓存服务和可集群部署&#xff0c;为缓存系统提供了高可用的运行环境&#xff0c…

Spring Boot 中的自动配置原理

2025/4/6 向全栈工程师迈进&#xff01; 一、自动配置 所谓的自动配置原理就是遵循约定大约配置的原则&#xff0c;在boot工程程序启动后&#xff0c;起步依赖中的一些bean对象会自动的注入到IOC容器中。 在讲解Spring Boot 中bean对象的管理的时候&#xff0c;我们注入bean对…

剑指Offer(数据结构与算法面试题精讲)C++版——day16

剑指Offer&#xff08;数据结构与算法面试题精讲&#xff09;C版——day16 题目一&#xff1a;序列化和反序列化二叉树题目二&#xff1a;从根节点到叶节点的路径数字之和题目三&#xff1a;向下的路径节点值之和附录&#xff1a;源码gitee仓库 题目一&#xff1a;序列化和反序…

windows server C# IIS部署

1、添加IIS功能 windows server 2012、windows server 2016、windows server 2019 说明&#xff1a;自带的是.net 4.5 不需要安装.net 3.5 尽量使用 windows server 2019、2016高版本&#xff0c;低版本会出现需要打补丁的问题 2、打开IIS 3、打开iis应用池 .net 4.5 4、添…