中间件专栏之MySQL篇——MySQL事务原理、锁机制分析

MySQL的事务性也是其重要特性之一。

什么是事务:事务的本质是并发控制的单元,是用户定义的一个操作序列。这些操作要么都做,要么都不做,是 一个不可分割的工作单位。

目的:事务的目的在于将数据库从一种一致性状态转换为另一种一致性状态,保证系统始终处于一个完整且正确的状态。

组成:事务可由一条非常简单的 SQL 语句组成,也可以由一组复杂的 SQL 语句组成。

特征:在数据库提交事务时,可以确保要么所有修改都已经保存,要么所有修改都不保存; 事务是访问并更新数据库各种数据项的一个程序执行单元。

事务控制语句:

-- 显示开启事务
START TRANSACTION | BEGIN-- 提交事务,并使得已对数据库做的所有修改持久化
COMMIT-- 回滚事务,结束用户的事务,并撤销正在进行的所有未提交的修改
ROLLBACK-- 创建一个保存点,一个事务可以有多个保存点
SAVEPOINT identifier-- 删除一个保存点
RELEASE SAVEPOINT identifier-- 事务回滚到保存点
ROLLBACK TO [SAVEPOINT] identifier

一、事务的ACID特性

1. ACID 四大特性

特性描述作用
A(原子性,Atomicity)事务是不可分割的最小工作单元,要么全部执行成功,要么全部回滚。确保事务中所有 SQL 语句要么都成功,要么都失败
C(一致性,Consistency)事务执行前后,数据库必须保持一致状态,不会破坏数据的完整性。保证数据在事务开始和结束后满足所有约束,如外键、唯一性等。
I(隔离性,Isolation)多个事务同时执行时,彼此不会相互影响,避免脏读、幻读等问题。MySQL 通过不同的隔离级别控制事务之间的可见性。
D(持久性,Durability)事务一旦提交,数据就会永久存储,即使系统崩溃也不会丢失。通过 redo logbinlog 保证事务的持久性。

2. ACID 详解

2.1 原子性(Atomicity)

事务必须是不可分割的整体

  • 如果某个操作失败,事务会回滚,撤销所有已执行的操作。
  • MySQL 通过 UNDO LOG(回滚日志)实现回滚机制

示例

START TRANSACTION;
UPDATE accounts SET balance = balance - 100 WHERE id = 1; 
UPDATE accounts SET balance = balance + 100 WHERE id = 2; 
ROLLBACK; -- 撤销所有操作

🔹 如果发生错误或断电,所有已执行的 SQL 语句都会被回滚,保证账户数据不丢失。


2.2 一致性(Consistency)

事务执行前后,数据必须满足完整性约束

  • 事务不能破坏数据库的外键约束、唯一性约束等规则。

示例 假设 accounts 表规定 balance >= 0,那么:

START TRANSACTION;
UPDATE accounts SET balance = balance - 100 WHERE id = 1;
UPDATE accounts SET balance = balance + 100 WHERE id = 2;
COMMIT;

🔹 如果某个账户余额变成负数,事务必须回滚,保持数据一致性


2.3 隔离性(Isolation)

多个事务并发执行时,彼此的修改互不影响

  • 解决脏读、不可重复读、幻读等问题。
  • MySQL 提供 四种事务隔离级别
    1. READ UNCOMMITTED(读未提交) → 允许读取未提交数据,可能导致脏读
    2. READ COMMITTED(读已提交) → 只能读取已提交数据,但可能出现不可重复读
    3. REPEATABLE READ(可重复读,MySQL 默认) → 多次查询结果一致,避免不可重复读
    4. SERIALIZABLE(可串行化) → 最高隔离级别,强制事务串行执行,性能最低

示例

SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ;
START TRANSACTION;
SELECT balance FROM accounts WHERE id = 1; -- 第一次读取
-- 其他事务修改 balance
SELECT balance FROM accounts WHERE id = 1; -- 仍然是原来的值
COMMIT;

🔹 可重复读(默认)能保证第二次查询仍然返回原始数据,避免不可重复读问题


2.4 持久性(Durability)

事务一旦提交,数据就必须永久存储

  • MySQL 通过 Redo Log(重做日志) 和 Binlog(二进制日志) 记录已提交的事务。
  • 即使服务器崩溃,重启后 MySQL 也能恢复数据

示例

START TRANSACTION;
UPDATE orders SET status = 'shipped' WHERE id = 123;
COMMIT; -- 事务提交后数据不会丢失

🔹 即使 MySQL 崩溃,订单状态仍然是 shipped

二、四大隔离级别详解

1. MySQL 四大事务隔离级别

MySQL 提供四种 事务隔离级别(由低到高):

隔离级别脏读不可重复读幻读性能SQL 设置
READ UNCOMMITTED(读未提交)❌ 可能❌ 可能❌ 可能✅ 性能最高SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
READ COMMITTED(读已提交)✅ 不可能❌ 可能❌ 可能⏳ 适中SET TRANSACTION ISOLATION LEVEL READ COMMITTED;
REPEATABLE READ(可重复读)MySQL 默认✅ 不可能✅ 不可能❌ 可能⏳ 适中SET TRANSACTION ISOLATION LEVEL REPEATABLE READ;
SERIALIZABLE(可串行化)✅ 不可能✅ 不可能✅ 不可能❌ 性能最低SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;

✅ = 解决了该问题
❌ = 可能出现该问题


2. 事务隔离级别问题详解

2.1 脏读(Dirty Read)

定义:一个事务可以读取到另一个未提交事务的修改。如果该事务回滚,则读取到的数据是无效的,造成数据不一致。

示例

  1. 事务 A 修改 balance = 1000 → 500(但未提交)。
  2. 事务 B 读取 balance = 500(但事务 A 可能回滚)。
  3. 事务 A 回滚balance 变回 1000,但事务 B 读到了错误的数据。

解决方法

  • READ COMMITTED 及以上级别可以避免脏读。

2.2 不可重复读(Non-Repeatable Read)

定义:同一事务内多次查询同一条记录,但结果不一致,因为另一个事务修改并提交了数据

示例

  1. 事务 A 读取 balance = 1000
  2. 事务 B 修改并提交 balance = 500
  3. 事务 A 再次读取 balance,发现变成 500,数据发生变化。

解决方法

  • REPEATABLE READ 及以上级别可以避免不可重复读。

2.3 幻读(Phantom Read)

定义:一个事务内多次查询相同条件的数据,但结果不一致,因为另一个事务插入/删除了数据

示例

  1. 事务 A 运行 SELECT * FROM users WHERE age > 30;,返回 5 条数据。
  2. 事务 B 插入 一条 age > 30 的数据并提交。
  3. 事务 A 再次运行 相同查询,返回 6 条数据,发生幻读。

解决方法

  • SERIALIZABLE 级别可以避免幻读(使用表级锁)。
  • InnoDB 默认通过 GAP 锁避免幻读

3. 事务隔离级别总结

隔离级别适用场景优缺点
READ UNCOMMITTED(读未提交)允许最高并发,但数据不安全可能发生脏读、不可重复读、幻读
READ COMMITTED(读已提交)大部分数据库的默认级别(如 Oracle),保证读到已提交数据可能发生不可重复读、幻读
REPEATABLE READ(可重复读)MySQL 默认适合大多数应用,保证同一事务多次读取结果一致可能发生幻读
SERIALIZABLE(可串行化)最高级别,数据最安全,所有事务串行执行

性能最低,适用于高安全性应用

三、MVCC详解

1. 什么是 MVCC(多版本并发控制)?

MVCC(Multi-Version Concurrency Control,多版本并发控制)是一种并发控制机制,可以让多个事务无锁并发执行,提高数据库性能,同时避免脏读、不可重复读等问题。

  • MVCC 主要用于 InnoDB 存储引擎,默认支持 REPEATABLE READ 隔离级别。
  • 通过 数据行的多个版本,使得读操作不会被写操作阻塞,提升并发性能。

2. MVCC 解决了哪些问题?

避免脏读:事务只能读取已经提交的数据。
避免不可重复读:在同一事务内,多次读取相同数据,结果保持一致。
提高并发性能:读操作无需加锁,避免锁竞争。

无法解决幻读:MVCC 无法防止插入数据带来的幻读,需要使用 GAP 锁


3. MVCC 的实现原理

3.1 MVCC 依赖的关键机制

MVCC 在 InnoDB 中主要依赖以下 三个重要的存储结构

  1. 隐藏列(隐式事务 ID 和回滚指针)
  2. Undo Log(回滚日志)
  3. Read View(读视图)

3.2 MVCC 关键实现细节

(1)隐藏列

InnoDB 为每个数据行额外存储两个隐藏列

  • trx_id:记录插入/修改该行的事务 ID。
  • roll_pointer:指向 Undo Log,可通过回滚日志获取数据的旧版本。

(2)Undo Log(回滚日志)
  • 作用:存储旧版本数据,使得历史版本可读(多版本存储)。
  • 实现
    • 每次 UPDATEDELETE,都会把旧值存入 Undo Log,并更新 roll_pointer 指向旧版本数据。
    • 事务回滚时,Undo Log 可用于恢复旧数据

(3)Read View(读视图)
  • 作用:控制事务可见性,决定事务是否可以看到某个版本的数据。
  • 核心逻辑
    1. 事务 T1 开启时,会生成 Read View(包含当前活跃事务的 trx_id 列表)。
    2. 查询数据时:
      • trx_id 小于 Read View 最小活跃事务 ✅ → 可见(数据已提交)。
      • trx_id 在活跃事务范围内 ❌ → 不可见(数据未提交)。
      • trx_id 大于当前事务 ID ❌ → 不可见(数据由新事务插入)。
    3. 事务 T1 只能看到 Read View 创建时的数据快照,即快照读

4. MVCC 读写方式

(1)快照读(Snapshot Read)

  • 读取的是数据的历史版本不加锁,提高查询性能。
  • 适用 SQL
  • 实现方式
    • Read View 读取符合当前事务可见性的数据。
    • Undo Log 提供历史版本数据。

(2)当前读(Current Read)

  • 读取的是最新版本数据,会加锁
  • 适用 SQL(需要保证数据一致性)
  • 实现方式
    • 事务需要读取最新版本数据,并阻塞其他事务修改该数据

5. MVCC 在不同隔离级别下的行为

隔离级别快照读当前读
READ UNCOMMITTED(读未提交)读取未提交的数据(不安全)直接读取最新版本
READ COMMITTED(读已提交)读取最新已提交版本加锁,读取最新数据
REPEATABLE READ(可重复读,MySQL 默认)同一事务内,多次查询结果一致加锁,读取最新数据
SERIALIZABLE(可串行化)强制事务串行执行加锁,阻塞其他事务

6. MVCC 适用范围

适用于 InnoDB 表(默认支持 MVCC)。
不适用于 MyISAM(MyISAM 不支持事务,不会存储多个数据版本)。
不适用于 SERIALIZABLE 级别(MVCC 失效,会强制加锁)。


7. MVCC 总结

机制作用
隐藏列(trx_id、roll_pointer)记录事务 ID、旧数据指针
Undo Log(回滚日志)存储数据的历史版本
Read View(读视图)确定事务可见性,控制快照读

MVCC 优势

✅ 读操作不加锁,并发性能高。
✅ 保证事务隔离性,避免脏读、不可重复读问题。

MVCC 局限

❌ 需要存储多个版本的数据,占用空间。
无法避免幻读(需要GAP 锁)。

适用场景

OLTP(高并发事务处理)场景,如 银行系统、电商订单管理
查询频繁但更新少的系统,如 分析报表

MVCC 是 MySQL 高性能事务控制的核心,合理利用 MVCC 机制,可以大幅提升数据库性能,同时保证数据一致性!

四、MySQL中锁机制

 

MySQL 的锁机制用于控制多个事务并发访问数据库时的数据一致性和并发性。不同的存储引擎(如 InnoDBMyISAM)实现的锁机制有所不同,InnoDB 采用更细粒度的锁控制,并支持 行级锁表级锁意向锁 等。


1. MySQL 锁的分类

MySQL 的锁可分为 全局锁表级锁行级锁,其中行级锁又包括共享锁、排他锁、意向锁、间隙锁等。

锁类型适用范围特点
全局锁作用于整个数据库FLUSH TABLES WITH READ LOCK,适用于备份数据,影响所有操作。
表级锁作用于整张表LOCK TABLES,如 MyISAM 存储引擎使用表锁,事务并发能力低。
行级锁作用于单行数据InnoDB 支持,提供更高的并发性能,但需要管理更多的锁信息。

2. MySQL 表级锁

2.1 表锁(Table Lock)

适用于 MyISAM,每次锁定整个表,不支持行级锁

操作SQL 语句特性
加读锁(共享锁)LOCK TABLES users READ;其他线程可读,但不可写
加写锁(排他锁)LOCK TABLES users WRITE;其他线程不可读也不可写
释放表锁UNLOCK TABLES;释放锁,其他事务可访问

缺点:影响并发,大多数情况下不推荐使用


3. MySQL 行级锁

3.1 共享锁(S 锁,Shared Lock)

  • 多个事务可同时读取数据,但不能修改数据
  • 适用于 SELECT ... LOCK IN SHARE MODE

🔹 应用场景:如果多个事务需要并发读取数据,并且不希望数据被修改,可使用共享锁。 

3.2 排他锁(X 锁,Exclusive Lock)

  • 排他性强,其他事务不能读取或修改被锁定的行
  • 适用于 SELECT ... FOR UPDATE

🔹 应用场景:用于更新前的查询,确保数据在更新前不会被其他事务修改。 

3.3 意向锁(Intent Lock)

  • 自动加锁,用于标识事务希望获取行级锁,防止表锁和行锁冲突。
  • InnoDB 自动管理,开发者无需手动控制
锁类型作用
意向共享锁(IS,Intent Shared)事务想要加 S 锁,表级锁不能加 X 锁
意向排他锁(IX,Intent Exclusive)事务想要加 X 锁,表级锁不能加 S/X 锁

🔹 应用场景:防止表级锁与行级锁冲突,提高锁管理效率。


3.4 间隙锁(Gap Lock,防止幻读)

作用:防止幻读,用于 REPEATABLE READ 隔离级别。

🔹 应用场景:当事务查询 age BETWEEN 18 AND 25 时,即使不存在数据,InnoDB 仍会锁住范围,防止其他事务插入 age=20 的新数据。


3.5 Next-Key Lock(间隙锁 + 行锁)

  • 锁定一行数据及其范围,防止新数据插入。
  • InnoDB 在 REPEATABLE READ 级别下默认使用,避免幻读。

🔹 如果 id=10 存在,InnoDB 不仅锁定该行,还会锁定 id=10 之后的索引范围**,防止插入新记录。


4. 死锁(Deadlock)及避免方法

4.1 什么是死锁?

死锁是指两个或多个事务互相等待对方释放锁,导致事务无法继续执行。

4.2 如何避免死锁?

方法策略
固定访问顺序保证所有事务按照相同顺序访问资源,避免循环等待。
减少锁的持有时间及时提交事务,避免长时间持有锁。
使用较高的隔离级别SERIALIZABLE 可以减少并发,避免复杂死锁。
索引优化减少锁定的行数,优化 WHERE 条件,避免锁住大量数据。

总结

锁类型作用适用存储引擎
全局锁锁住整个数据库,影响所有操作所有存储引擎
表级锁锁住整张表,适用于 MyISAMMyISAM,InnoDB
行级锁只锁住特定行,提高并发性能InnoDB
共享锁(S 锁)允许读取,不允许修改InnoDB
排他锁(X 锁)其他事务不能读也不能写InnoDB
意向锁(IS/IX)防止表级锁和行级锁冲突InnoDB
间隙锁(Gap Lock)防止幻读,锁定范围InnoDB
Next-Key Lock行锁 + 间隙锁,避免幻读InnoDB

 

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

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

相关文章

机器学习的三个基本要素

机器学习的基本要素包括模型、学习准则(策略)和优化算法三个部分。机器学习方法之间的不同,主要来自其模型、学习准则(策略)、优化算法的不同。 模型 机器学习首要考虑的问题是学习什么样的模型(Model&am…

集成方案 | Docusign 能与哪些应用程序集成?

如何实现 Docusign 与多种系统平台之间的高效集成? 在企业跨境签约场景中,员工常常需要在电子签系统与办公应用(如钉钉、企业微信)、CRM、ERP 等系统之间来回切换,手动上传合同、下载签署文件并同步数据。这种繁琐的操…

2025华为OD机试真题目录【E卷+A卷+B卷+C卷+D卷】持续收录中...

摘要 本专栏提供2025最新最全的华为OD机试真题库(EABCD卷),包括100分和200分题型。题目包含题目描述、输入描述、用例、备注和解题思路、多种语言解法(Java/JS/Py/C/C)。希望小伙伴们认真学习、顺利通过。 声明 本专…

广域互联网关键技术详解(GRE/LSTP/IPsec/NAT/SAC/SPR)

《广域互联网关键技术详解》属于博主的“广域网”专栏,若想成为HCIE,对于广域网相关的知识需要非常了解,更多关于广域网的内容博主会更新在“广域网”专栏里,请持续关注! 一.前言 广域互联技术纷杂多样,不…

AF3 _correct_post_merged_feats函数解读

AlphaFold3 msa_pairing 模块的 _correct_post_merged_feats 函数用于对合并后的特征进行修正,确保它们符合预期的格式和要求。这包括可能的对特征值进行调整或进一步的格式化,确保合并后的 FeatureDict 适合于后续模型的输入。 主要作用是: 在多链蛋白质 MSA(多序列比对)…

Docker 学习(三)——数据管理

容器中的管理数据主要有两种方式: 数据卷 (Data Volumes): 容器内数据直接映射到本地主机环境; 数据 卷容器( Data Volume Containers): 使用特定容器维护数据卷 1.数据卷 数据卷…

基于SSM+Vue+uniapp的考研交流(带商城)小程序+LW示例参考

系列文章目录 1.基于SSM的洗衣房管理系统原生微信小程序LW参考示例 2.基于SpringBoot的宠物摄影网站管理系统LW参考示例 3.基于SpringBootVue的企业人事管理系统LW参考示例 4.基于SSM的高校实验室管理系统LW参考示例 5.基于SpringBoot的二手数码回收系统原生微信小程序LW参考示…

2025-03-04 学习记录--C/C++-PTA 练习5-3 字符金字塔

合抱之木,生于毫末;九层之台,起于累土;千里之行,始于足下。💪🏻 一、题目描述 ⭐️ 二、解题步骤 ⭐️ 第1步、把字符和一个空格看作整体,即"G_"; 第2步、外…

DeepSeek集成到VScode工具,让编程更高效

DeepSeek与VScode的强强联合,为编程效率树立了新标杆。 DeepSeek,一款卓越的代码搜索引擎,以其精准的索引和高速的检索能力,助力开发者在浩瀚的代码海洋中迅速定位关键信息。 集成至VScode后,开发者无需离开熟悉的编辑…

前端-css(预编译器sass)

1.sass(scss->sass第三代) Sass3 -> Scss(Sassy CSS),SCSS(Sassy CSS) 是 CSS 语法的扩展. 2.scss注释 Sass 支持标准的 CSS 多行注释 /* */,以及单行注释 //,前者会 被完整输出到编译后的 CSS 文件中,而后者则不会 3.scss定义变量 …

【计算机网络入门】初学计算机网络(十一)重要

目录 1. CIDR无分类编址 1.1 CIDR的子网划分 1.1.1 定长子网划分 1.1.2 变长子网划分 2. 路由聚合 2.1 最长前缀匹配原则 3. 网络地址转换NAT 3.1 端口号 3.2 IP地址不够用? 3.3 公网IP和内网IP 3.4 NAT作用 4. ARP协议 4.1 如何利用IP地址找到MAC地址…

Android 获取jks的SHA1值:java.io.IOException: Invalid keystore format

命令生成 keytool -list -v -keystore 全路径.jks -alias 别名 -storepass 密码 -keypass 密码 1、遇到 的问题: 通过快捷键 ‘win r’ 启动的小黑框运行上面的命令会出现下面这个错误keytool 错误: java.io.IOException: Invalid keystore format 2、解决问题 …

掌握 ElasticSearch 聚合查询:Aggregations 入门与实战

掌握 ElasticSearch 聚合查询:Aggregations 入门与实战 一、引言 (Introduction)二、数据准备 (Data Preparation)2.1 创建索引 (Create Index)2.2 批量导入数据 (Bulk Import Data) 三、聚合查询基础 (Aggregation Basics)3.1 什么是聚合查询?(What are…

Microsoft.Office.Interop.Excel 的简单操作

Microsoft.Office.Interop.Excel 的简单操作 1、安装 Microsoft.Office.Interop.Excel2、声明引用 Microsoft.Office.Interop.Excel3、简单的新建 EXCEL 操作代码4、将 DataGridView 表数据写到 EXCEL 操作代码5、将 EXCEL 表数据读取到 C# 数据表 DataTable 操作代码 1、安装 …

LLM 对话框组件 | 字节青训营前端开发项目

系统介绍 LLM对话框项目系统介绍 一、项目概述 选题背景随着人工智能技术的飞速发展,自然语言处理(NLP)领域取得了显著进展,其中对话系统(Dialog System)作为NLP的重要应用方向,正逐渐渗透到人们的日常生活中。从智能客服到语音助手,从智能家居到在线教育,对话系统以…

k8s命名空间和资源配额

在现代的云计算环境中,容器化技术已成为主流。而 Kubernetes(简称 k8s)作为一项开源的容器编排系统,广泛应用于各类场景。本文将详细介绍关于 k8s 中的命名空间和资源配额,帮助你更好地理解和管理你的集群资源。 k8s …

从统计学视角看机器学习的训练与推理

从统计学视角看机器学习的训练与推理 目录 引言:统计学与机器学习的奇妙缘分训练与推理:你得先学会“看数据”再“用数据”最大似然估计(MLE):从直觉到数学证明 3.1 伯努利分布的MLE3.2 单变量高斯分布的MLE3.3 多元…

AI赋能企业协作4-NL2Sql技术路线

1.1 对话即服务的一点思考 在数智化转型的过程中,基于即时通信(IM)的协作平台正悄然成为企业智能化转型的“新基建”。协作平台天然具备高频交互、实时协同和场景化落地的特性,仿佛是为对话式AI量身定制的试验场——员工在熟悉的聊…

批量提取 Word 文档中的页面

如何将 Word 文档中的页面提取出来形成一个新的文档呢?比如将 Word 文档中的第一页提取出来、将 Word 文档中的最后一页提取出来、再或者将 Word 文档中的中间几页提取出来等等。人工的处理肯定非常的麻烦,需要新建 Word 文档,然后将内容复制…

Sqlserver安全篇之_启用TLS即配置SQL Server 数据库引擎以加密连接

官方文档 https://learn.microsoft.com/zh-cn/sql/database-engine/configure-windows/configure-sql-server-encryption?viewsql-server-ver16 https://learn.microsoft.com/zh-cn/sql/database-engine/configure-windows/manage-certificates?viewsql-server-ver15&pre…