MySQL系列


文章目录

  • MySQL系列
  • 一、什么是事务
    • 1.1事务的核心概念
    • 1.2、 事务的四大属性(ACID)
      • 1.2.1 原子性(Atomicity)
      • 1.2.2 一致性(Consistency)
      • 1.2.3 隔离性(Isolation)
      • 1.2.4 持久性(Durability)
    • 1.3 为什么会出现事务
    • 1.5 事务的版本支持
  • 二、事务操作
    • 2.1 事务的提交
    • 2.2 事务的基本操作
    • 2.3 单挑sql和事务的关系
  • 三、事务隔离级别
    • 3.1 隔离级别
    • 3.2 隔离级别的操作
      • 3.2.1查看隔离级别
      • 3.2.2 设置隔级别
  • 四、隔离级别的具体表现
    • 4.1 读未提交
    • 4.2 读提交
    • 4.3 可重复读
    • 4.4 串行化
    • 4.5 总结


上一篇:MySQL 索引:结构、对比与操作实践指南

一、什么是事务

1.1事务的核心概念

事务是数据库操作中的核心概念,其核心定义可概括为:
由一组DML语句(数据操纵语言,如INSERT、UPDATE、DELETE等)组成,这些语句在逻辑上存在紧密相关性(例如完成一次转账需同时涉及转出账户扣款和转入账户收款)。
作为一个不可分割的整体,这组DML语句遵循要么全部成功执行,要么全部失败的原则——只要其中任一语句执行出错,所有已执行的操作都会被撤销。
此外,事务确保:不同客户端在操作过程中,看到的数据状态可能是不相同的,以此避免并发操作导致的数据混乱。

一个事务不仅仅只是简单的sql集合,同时满足如下四个属性

1.2、 事务的四大属性(ACID)

这里先简单了解,后面的内容,会围绕这四大特定详细介绍
在这里插入图片描述
MySQL做为网络服务器一定会存在并发访问的场景,而这就可能发生图中错误,要想解决这个问题,就需要保证:
1.买票的过程得是原子
2. 买票互相不能影响
3. 买完票要永久有效
4. 买前,和买后都要是确定的状态

为了解决这个问题,MySQL对事务做了如下要求:

1.2.1 原子性(Atomicity)

事务(transaction)里的所有操作是一个不可分割的整体,要么全部成功执行,要么全部回滚撤销 。若执行中出现错误,会回滚(Rollback)到事务开始前状态,如同事务从未执行过,保障操作的“一荣俱荣,一损俱损”。

1.2.2 一致性(Consistency)

事务执行前和执行后,数据库的完整性(如数据精度、关联性等规则)不会被破坏 。写入的数据必须严格符合预设规则,确保数据库能按预期提供服务,维持数据的安全可靠。

1.2.3 隔离性(Isolation)

数据库支持多个事务并发读写、修改数据,且能通过隔离性避免因事务交叉执行导致数据混乱 。隔离性有不同级别,常见的有:读未提交(Read Uncommitted )、读提交(Read Committed )、可重复读(Repeatable Read )、串行化(Serializable ),不同级别平衡并发效率与数据一致性。

1.2.4 持久性(Durability)

事务成功提交后,对数据的修改会永久留存 ,即便系统故障(如断电、崩溃),修改也不会丢失,保障数据最终的“稳定落地”。

这四大属性的英文首字母缩写为 ACID ,是事务机制的核心保障。

1.3 为什么会出现事务

MySQL中事务的设计,本质是为应用程序访问数据库时提供便利——它能极大简化编程模型,让开发者无需手动处理各种潜在错误与并发问题。

试想,若没有事务机制,编写数据库访问程序时,需额外考虑的问题会极为繁琐:比如网络突然中断如何处理?服务器意外宕机后数据如何恢复?多个操作同时修改同一份数据时如何避免冲突?…… 而有了事务,开发者只需关注“提交(Commit)”或“回滚(Rollback)”两种操作即可,上述复杂场景都由事务机制自动处理。

由此可见,事务并非数据库系统与生俱来的组件,而是专为服务应用层而设计的工具,其核心价值在于降低应用程序与数据库交互时的开发复杂度。

1.5 事务的版本支持

show engines;

在这里插入图片描述
可以看到并不是所有的引擎都支持事务。

二、事务操作

2.1 事务的提交

事务的提交方式常见的有两种:

  • 自动提交
  • 手动提交

查看是否的提交方式:

show variables like 'autocommit';

在这里插入图片描述
可以看到默认情况下是打开的;

更改自动提交:

// 禁止自动提交:
SET AUTOCOMMIT=0;

在这里插入图片描述

// 开启自动提交:
SET AUTOCOMMIT=1;

在这里插入图片描述
两者的具体区别后面会做验证

2.2 事务的基本操作

接下来我会营造并发场景展开介绍

准备工作:
为了便于演示,先将mysql的默认隔离级别设置成读未提交

set global transaction isolation level READ UNCOMMITTED;

重启终端(也可以重新登录MySQL),进行查看隔离级别

select @@transaction_isolation;

在这里插入图片描述
创建测试表

create table if not exists account(
id int primary key,
name varchar(50) not null default '',
blance decimal(10,2) not null default 0.0
)ENGINE=InnoDB DEFAULT CHARSET=UTF8;

启动事务(两种方法):

  • start transaction;
  • begin
    设置保存点(标记,方便回滚)
  • savepoint 保存点名

在这里插入图片描述
可以看到我们在read uncommitted级别的隔离下,并发操作一整表时,事务发起者向表中插入后不需要等到事务提交,并发参与者立马可以看到,事务发起者在执行操作时也可以边操作边插入保存点,可以通过rollback to 保存点名回滚到设置保存点前的状态(若为设置保存点,可以直接使用rollback直接回滚到事务开始状态),此时若我们的操作失败、服务器奔溃,就会自动回滚到,执行事务前的状态。
在这里插入图片描述
可以看到事务发起者异常退出时,事务就会回滚到开始前状态,数据不会被持久化,采用这种事务的形式,就实现了原子化的概念。
有很多场景在这里不可能全部演示,你可以自己尝试,使用ctrl+\可以模拟服务退出
commit提交事务
当我们提交事务后,数据就会永久保存,再次回滚就不会回到之前了
在这里插入图片描述
只要事务发起者commit后数据机会持久化,即使再次回滚数据依然保存。

我们不是开启自动提交了吗?我什么异常退出后,事务无法自动提交呢?
MySQL要求,手动发起的事务,必须要手动提交,而自动提交是帮助默认发起的事务做提交的,下面我们来验证一下。

2.3 单挑sql和事务的关系

关闭自动提交 set autocommit=0
在这里插入图片描述
可以看到,当关闭自动提交后,事务发起者向表中插入数据时,若MySQL服务异常退出,数据会回滚到之前状态。这是因为在MySQL中,单条SQL语句默认也会被当作事务处理,其提交依赖自动提交功能。当关闭自动提交后,即便执行单条SQL(本质也是事务范畴),因未手动提交,异常退出时就无法完成提交,最终触发回滚 。
相反的,在正常情况下,自动提交方法是打开的,那么即使mysql崩溃了,它数据也是会自动提交成功的(所以执行的所有sql本质都是事务!!只不过进行了自动提交)。

总结

  1. 只要输入 begin 或者 start transaction,事务便必须要通过 commit 提交,才会持久化,与是否设置 set autocommit 无关。
  2. 事务可以 手动回滚,同时,当操作异常,MySQL 会 自动回滚
  3. 对于 InnoDB,每一条 SQL 语言都默认封装成事务,自动提交select 有特殊情况,因为 MySQL 有 MVCC)。
  4. 从上面的例子,我们能看到事务本身的 原子性(回滚),持久性(commit)。
  5. 如果没有设置 保存点,也可以回滚,只能回滚到事务的开始,直接使用 rollback(前提是事务还没有提交)。
  6. 如果一个事务被 提交了(commit),则 不可以回退(rollback)
  7. 可以选择回退到 哪个保存点
  8. InnoDB 支持事务MyISAM 不支持事务
  9. 开始事务可以使用 start transaction 或者 begin

三、事务隔离级别

首先需要明确:MySQL服务作为网络服务器,可能同时被多个客户端进程(线程)访问,且访问以事务形式进行。一个事务可能包含多条SQL,因此任何事务都存在三个阶段:

  • 执行前
  • 执行中
  • 执行后

原子性的核心,是让用户层要么看到事务执行前的状态,要么看到执行后的状态。若执行中出现问题,可随时通过回滚撤销操作。因此,单个事务对用户呈现的核心特性就是原子性

但需注意:所有事务都有执行过程,当多个事务并发执行多条SQL时,仍可能出现互相影响——例如,多个事务同时访问同一张表甚至同一行数据
而有些情况不会对操作造成影响(如:并发读取数据),有些情况则会导致结果出错(如:一端删除、一端查找可能引发执行错误)。

  • 因此,数据库中为保证事务执行过程尽量不受干扰,存在一个重要特征:隔离性
  • 同时,数据库允许事务受不同程度的干扰,由此衍生出另一种重要特征:隔离级别

3.1 隔离级别

读未提交(Read Uncommitted)

  • 核心特征:所有事务可看到其他事务未提交的执行结果
  • 问题:相当于无隔离性,会引发脏读、幻读、不可重复读等所有并发问题。 (上面的测试就是使用的这个隔离级别)

读提交(Read Committed)

  • 核心特征:事务仅能看到其他事务已提交的修改(满足隔离性的基础定义)。
  • 问题:会导致不可重复读(同一事务中多次 select 可能得到不同结果)。
  • 默认情况:是大多数数据库的默认隔离级别(非 MySQL 默认)。

可重复读(Repeatable Read)

  • 核心特征:确保同一事务中,多次读取数据时看到的数据行一致
  • 问题:仍可能存在幻读
  • 默认情况MySQL 的默认隔离级别

串行化(Serializable)

  • 核心特征:事务的最高隔离级别,通过强制事务排序避免冲突,解决幻读问题(原理是对读取的数据行加共享锁)。
  • 问题:可能导致超时和锁竞争,性能极低。
  • 使用场景:实际生产中基本不使用(隔离级别过于严格)。

3.2 隔离级别的操作

3.2.1查看隔离级别

查看全局隔离级别

select @@global.transaction_isolation;

在这里插入图片描述
查看当前会话隔离级别

select @@session.transaction_isolation;
select @@transaction_isolation;

在这里插入图片描述

3.2.2 设置隔级别

设置当前会话 or 全局隔离级别语法:

set [ session | global ] transaction isolation level { read uncommitted | read committed | repeatable read | serializable}

设置当前会话的隔离级别

set session transaction isolation level read committed;

在这里插入图片描述
设置全局的隔离级别

set global transaction isolation level serializable;

在这里插入图片描述
可以看到全局隔离级别的改变,不会对以创建的会话产生作用,而他的作用是设置新建的会话。
也就是说重启mysql后就会变成全局的隔离级别

四、隔离级别的具体表现

4.1 读未提交

读未提交:几乎不施加锁机制,虽执行效率高,但存在严重问题

其核心问题是脏读(dirty read):一个事务在执行过程中,能读到另一个未提交事务的更新(或其他操作)—— 因为事务执行有过程性,只要一个用户修改了表,即便未执行 commit,其他用户无需等待提交就能立即看到这些未确认的操作

这正是“读未提交”的本质:事务只要执行了SQL(未提交),其对表的操作就会被其他事务可见
在这里插入图片描述

脏读具体来说:

  1. 事务A(发起者) 对数据做了修改(如更新某条记录),但尚未执行 commit(可能处于执行中或未完成);
  2. 事务B(并发者) 在自己的事务中读取到了事务A未提交的修改结果;
  3. 若事务A因异常(如代码错误、数据库崩溃等)发生回滚,其修改会被撤销,数据恢复到初始状态;
  4. 此时事务B之前读取到的“未提交数据”就成了无效的错误数据,基于该数据的后续操作(如计算、决策、更新)也会随之出错。

这种“读到临时且可能被回滚的数据”的现象,正是脏读。

4.2 读提交

为方便截取我先把表清空
在这里插入图片描述
在读提交隔离级别中:

  • 事务发起者未提交时,事务并发者看不到其操作
  • 一旦发起者执行 commit 提交,即使并发者的事务未结束,也会立即看到提交后的修改。

这会导致 不可重复读(non-repeatable read) 问题:同一事务内,相同的读取操作在不同时间点(事务仍在执行中)返回不同结果

从逻辑上,一个事务提交后其他事务能看到最新数据是合理的,但站在并发事务的一致性角度,同一事务内多次读取应保持一致,否则会破坏事务内数据的稳定性——这正是不可重复读的问题核心。

示例

  1. 事务A(并发者)启动,读取到 account 表中 id=1 的余额为 1000 元。
  2. 事务B(发起者)启动,将 id=1 的余额改为 2000 元并提交。
  3. 事务A未结束,再次读取 id=1 的余额,结果变为 2000 元——同一事务内两次读取结果不同,即不可重复读。

4.3 可重复读

可重复度是MySQL的默认隔离级别
在这里插入图片描述
可重复读(MySQL 默认隔离级别)的核心特性是:同一事务在执行期间,多次读取数据会保持一致,直到自身事务提交后,才能看到其他事务的修改结果。

例如:终端A在事务中执行 INSERT 操作,终端B在自身事务周期内多次查看,均不受终端A未提交或已提交数据的影响,这符合可重复读的特点。

但多数数据库的可重复读存在一个问题:无法屏蔽其他事务新插入(INSERT)的数据

原因在于:隔离性通常通过对已存在数据加锁实现,而待插入的数据因尚未存在,无法被传统锁机制覆盖。因此,同一事务内多次查询时,可能会读到其他事务新插入的记录,出现“多次查找结果不一致、新增了未预期的记录”的现象,这被称为 幻读(phantom read)

关键差异:MySQL 的可重复读(RR 级别)通过 Next-Key 锁(间隙锁 + 行锁) 解决了幻读问题——不仅锁定已有数据行,还锁定数据间隙,防止其他事务在间隙中插入新记录,从而保证事务内读取结果的稳定性。

4.4 串行化

前面三个隔离级别主要特点是:一方在修改数据(CUD操作),一方在读取数据(R操作),但是面对双方都在修改数据的场景(CUD操作),我们就必须通过加锁来实现了

对所有事务操作全部加锁,进行事务的串行化,但是只要串行化,效率很低,几乎完全不会被采用。
在这里插入图片描述
可以看到在串行化隔离级别下,并发的事务查询并不会受到锁的约束,但如果想要对数据做修改,sql就会被阻塞(阻塞时间过长就会报错)。
在这里插入图片描述
当有一方提交事务后,锁就会被释放,阻塞的sql就会再次执行。

4.5 总结

隔离级别越严格,数据安全性越高,但数据库并发性能越低,实际应用中需在两者间寻找平衡。

  • 不可重复读的重点是修改和删除:同一条件下,两次读取同一数据,结果值不同。
  • 幻读的重点是新增:同一条件下,两次读取的记录数量不同。

从实例中可看出,事务存在长事务、短事务的概念。事务间的互相影响,在并行执行且均未提交时尤为显著。
在这里插入图片描述

一致性(Consistency)

  • 核心定义:事务执行结果必须使数据库从一个一致性状态切换到另一个一致性状态。当数据库仅包含所有成功提交事务的结果时,处于一致性状态;若因系统中断导致未完成事务的修改写入数据库,则数据库会处于不一致状态

  • 保障关系:一致性通过原子性(事务要么全成、要么全滚)提供基础保障。

  • 技术支撑:从技术层面,一致性(C)通过原子性(A)、隔离性(I)、持久性(D) 共同保障(即 ACID 中的 AID 支撑 C)。


后面这篇文章是对隔离性更深层次的介绍

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

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【MCU EEPROM开发教程】

简单来说把eeprom芯片当成一个传感器来使用,通过IIC/SPI等协议对芯片进行读写操作,具体的读写操作涉及到一些算法—怎么样读写更加快速,以及一些异常错误处理。 应用场景: 对于一些掉电也不能丢失的数据要存在eeprom/flash中&…

Docker将镜像搬移到其他服务上的方法

导出/加载镜像(保留分层、标签)和导出/导入容器快照(仅文件系统,丢失镜像历史与标签)。 一、把镜像打包带走(推荐) 适合把一个或多个镜像搬到离线/内网机器,保留分层与标签。 在源服…

Ubuntu 系统安装 Miniconda 完整方法与注意事项

一、完整安装步骤 1. 下载 Miniconda 安装包 Miniconda 安装包为 .sh 格式脚本,下载途径分两种: 方式 1:浏览器下载(适合新手) 访问 Miniconda 官方下载页,选择对应系统版本(Ubuntu 选 Miniconda3-latest-Linux-x86_64.sh),默认保存到用户目录的 ~/Downloads 文件夹…

【后端】数据库四大范式详细解析

梳理一下 MySQL(或关系型数据库)中的第一、二、三、四范式,这是数据库设计中非常重要的规范化理论。1️⃣ 第一范式 (1NF:First Normal Form)定义:字段具有原子性,不可再分。数据表中每一列都必须是不可分割…

HarmonyOS后台任务调度:JobScheduler与WorkManager实战指南

本文将深入探讨HarmonyOS 5(API 12)中的后台任务调度机制,重点讲解JobScheduler和WorkManager的使用方法、适用场景及最佳实践,帮助开发者实现高效、智能的后台任务管理。 1. 后台任务调度概述 HarmonyOS提供了两种主要的后台任务…

Prompt工程实践

你在写prompt时候,是不是总觉得大模型它不听话。要么答非所问、要么一堆废话。扒开思考过程仔细阅读时而觉得它聪明绝顶,时而又觉得它愚蠢至极。明明已经对了怎么又推理到错的地方去了,明明在提示词中提醒过了不要这么思考它怎么就瞎想了。这…

基于springboot的毕业旅游一站式定制系统

博主介绍:java高级开发,从事互联网行业六年,熟悉各种主流语言,精通java、python、php、爬虫、web开发,已经做了多年的设计程序开发,开发过上千套设计程序,没有什么华丽的语言,只有实…

输入1.8V~5.5V 输出28V DCDC升压芯片TLV61046A

今天来一款TI的升压芯片TLV61046A。输入电压范围1.8V~5.5V。最高可以输出28V。开关电流980mA,那具体能输出多大的电流就得看输入输出的电压了。以上面的输入3.6V输出12V为例,效率是85%,那最高可以输出的电流就差不多只有200mA左右。封装也是非…

ubuntu22.04源码安装ffmpeg-4.4

# ubuntu22.04源码安装ffmpeg-4.4cd /tmpwget https://ffmpeg.org/releases/ffmpeg-4.4.6.tar.xztar -xvf ffmpeg-4.4.6.tar.xzcd ffmpeg-4.4.6apt updateapt install -y yasm pkg-config libx264-dev libx265-dev libvpx-dev libfdk-aac-dev libmp3lame-dev libopus-dev libav…

Pyhon中字符串常用的函数

一、字符串的格式化1.format()方法format()是 Python 中用于字符串格式化的方法,通过占位符(如 {})动态插入变量或表达式。name小明 age18 grade99.556245585 information"我是{},今年{}岁了,考试得分:{:.2f}&quo…

小迪安全v2023学习笔记(八十一讲)—— 框架安全ThinkPHPLaravelStruts2SpringBootCVE复现

文章目录前记服务攻防——第八十一天开发框架安全&SpringBoot&Struts2&Laravel&ThinkPHP&CVE复现开发框架 - 常见语言开发框架PHP - 框架安全-Thinkphp&LaravelLaravel漏洞介绍漏洞复现CVE-2021-3129ThinkPHP漏洞介绍漏洞复现CVE-2018-1002015QVD-2022…

从音频到Token:构建原神角色语音识别模型的完整实践

本文将带你从零实现一个基于音频Token化的角色语音识别系统,完整复现原神角色语音分类任务,包含数据处理、模型训练和推理全流程。音频波形通过滑动窗口转换为数值Token序列的过程 一、为什么需要音频Token化? 传统音频处理通常依赖MFCC、频谱…

关于TCP和UDP两种网络协议的区别

1、tcp协议TCP (Transmission Control Protocol - 传输控制协议)TCP 的核心目标是为应用层提供一条可靠的、无差错的、有序的字节流通道。主要特点:面向连接:在数据传输之前,必须通过“三次握手”建立稳定的连接,传输结束后通过“…

Alibaba Lens:阿里巴巴推出的 AI 图像搜索浏览器扩展,助力B2B采购

本文转载自:https://www.hello123.com/alibaba-lens ** 一、🌟 一键截图,轻松找货:采购神器 Alibaba Lens 详解 Alibaba Lens 是阿里巴巴集团专为全球 B2B 采购商打造的一款智能浏览器插件(支持 Chrome 等主流浏览器…

WPF常见问题清单

1.Grid 内容自动换行及自适应行高 <DataGrid Grid.Row"1" FontSize"14" IsReadOnly"True" VerticalScrollBarVisibility"Auto" RowHeight"NaN" ItemsSource"{Binding List}" AutoGenerateColumns"False…

Linux驱动开发笔记(十)——中断

视频&#xff1a;第13.1讲 Linux中断实验-Linux内核中断框架简介_哔哩哔哩_bilibili 文档&#xff1a;《【正点原子】I.MX6U嵌入式Linux驱动开发指南V1.81.pdf》五十一章 1. 中断API函数 每个中断都有一个中断号&#xff0c;通过中断号即可区分不同的中断。在Linux 内核中使用一…

ubuntu18.04安装PCL1.14

简化版说明 1. 安装依赖库&#xff1a; (1) boost1.84 &#xff08;https://www.boost.org/releases/1.84.0/&#xff09; tar vxf boost_xxx.tar.gz ./bootstrap.sh --prefix/usr/local/ ./b2 sudo ./b2 install (2) vtk9.1.0 &#xff08;https://vtk.org/files/releas…

python将pdf转txt,并切割ai

python将pdf转txt&#xff0c;并切割ai step1:pdf转换 from PIL import Image import pytesseract import os import tempfile from pdf2image import convert_from_path# 设置 Tesseract 路径 pytesseract.pytesseract.tesseract_cmd rC:\Users\wangrusheng\AppData\Local\Pr…

Ubuntu22.04更换阿里镜像源,ubuntu更换源

在 Ubuntu 22.04 上更换为阿里云镜像源可以加速软件包的下载和更新&#xff0c;大幅提升系统更新速度。以下是更换阿里云镜像源的步骤&#xff1a;1. 备份现有源列表在更换镜像源之前&#xff0c;建议先备份当前的源配置文件&#xff1a;bashsudo cp /etc/apt/sources.list /et…

Git版本控制工具+基础命令

Git是什么&#xff1f;Git是目前世界上最先进的分布式版本控制系统代码托管平台&#xff1a;Gitlab/Github/Gitee&#xff08;码云&#xff09;什么是版本控制系统&#xff1f;指对软件开发过程中各种程序代码、配置文件及说明文档等文件变更的管理。版本控制最主要的功能就是追…