MySQL学习笔记(2)并发问题与事务隔离级别

本文参考:https://javaguide.cn/database/mysql/transaction-isolation-level.html

并发事务问题

脏读:一个事务读到了另一个事务中未提交的数据

不可重复读:一个事务先后读取同一条数据,当时两次获取到的结果不同

幻读:一个事务按照条件查询数据时,没有查到对应的数据行,当时在插入数据时,又发现这行数据已经存在

SQL中标准的四个隔离级别:

  • 读取未提交(READ-UNCOMMITTED):允许读取尚未提交的数据变更。
  • 读取已提交(READ-COMMITTED):允许读取并发事务已经提交的数据。
  • 可重复读(REPEATABLE-READ):对同一字段的多次读取结果都是一致的,除非数据是被本身事务自己所修改。
  • 可串行化 (SERIALIZABLE):所有的事务依次逐个执行。

    MySQL InnoDB 存储引擎的默认 支持的隔离级别是 REPEATABLE-READ(可重读),但是通过MVCC 机制和 Next-Key Lock 机制防止了幻读现象的出现。

InnoDB 的 MVCC 机制

InnoDB 使用多版本并发控制(MVCC)来实现一致性读。MVCC 的核心思想是:

  • 每个事务都有一个唯一的事务 ID(事务版本号)。
  • 数据行会保存多个版本(通过隐藏的列 DB_TRX_ID 和 DB_ROLL_PTR 记录版本信息)。
  • 事务读取数据时,会根据自己的事务 ID 看到数据在事务开始时的快照版本,而不是实时版本。

MVCC 如何防止幻读?

  • 在 REPEATABLE-READ 级别下,事务 A 的快照版本是固定的,它只能看到在事务开始时已经存在的数据行。
  • 即使其他事务插入了新行,这些新行不会出现在事务 A 的快照版本中,因此事务 A 不会看到这些新行,从而避免了幻读。

Next-Key Lock 机制

InnoDB 在 REPEATABLE-READ 级别下使用 Next-Key Lock 来进一步防止幻读。Next-Key Lock 是行锁(Record Lock)和间隙锁(Gap Lock)的结合:

  • 行锁(Record Lock):锁定已存在的数据行。
  • 间隙锁(Gap Lock):锁定数据行之间的间隙,防止其他事务插入新行。

Next-Key Lock 如何防止幻读?

  • 当事务 A 对某个范围的数据进行读取时,InnoDB 会使用 Next-Key Lock 锁定整个范围(包括已存在的行和行之间的间隙)。
  • 如果事务 B 尝试在这个范围内插入新行,会被间隙锁阻塞,直到事务 A 提交或回滚。
    这样,事务 A 在整个事务期间都能保证范围内的数据不会被其他事务插入新行,从而防止了幻读。

不可重复读和幻读的区别是一个读取的一行,一个读取的是多行吗?

不可重复读和幻读的区别并不是由读取单行或多行决定的,而是由数据变化的类型决定的。以下是两者的详细区别:

1. 不可重复读(Non-Repeatable Read)

不可重复读是指在同一个事务中,两次读取同一行数据时,数据的内容发生了变化。这种现象通常是由于其他事务对该行数据进行了更新(UPDATE)操作。

特点:
  • 数据行不变:数据行的主键或唯一标识没有变化。
  • 数据内容变化:数据行的内容(字段值)发生了变化。
  • 解决方法:通过记录锁(Record Lock)锁定数据行,防止其他事务更新该行。

2. 幻读(Phantom Read)

幻读是指在同一个事务中,两次读取同一范围的数据时,数据的集合发生了变化。这种现象通常是由于其他事务在该范围内插入(INSERT)或删除(DELETE)了数据行。

特点:
  • 数据范围不变:查询的条件范围没有变化。
  • 数据集合变化:查询结果集中出现了新的行或某些行消失了。
  • 解决方法:通过间隙锁(Gap Lock)或 Next-Key Lock(记录锁 + 间隙锁)锁定数据范围,防止其他事务在该范围内插入或删除数据。

3. 不可重复读 vs. 幻读

  • 不可重复读 :关注的是数据行的内容变化,通常是由于其他事务对同一行数据进行了更新操作。
  • 幻读 :关注的是数据范围内的集合变化,通常是由于其他事务在范围内插入或删除了数据。
相关推荐
Chef_Chen3 分钟前
从0开始学习R语言--Day64--决策树回归
学习·决策树·r语言
无望__wsk41 分钟前
ospf笔记
服务器·网络·笔记
Aplis41 分钟前
ETCD学习之路
数据库·学习·etcd
翔云1234561 小时前
MySQL 高并发下如何保证事务提交的绝对顺序?
数据库·mysql
玖剹1 小时前
Linux文件系统:从内核到缓冲区的奥秘
linux·c语言·c++·笔记·ubuntu
叁沐1 小时前
MySQL 23 MySQL是怎么保证数据不丢的?
mysql
知识分享小能手1 小时前
Vue3 学习教程,从入门到精通,Vue3 中使用 Axios 进行 Ajax 请求的语法知识点与案例代码(23)
前端·javascript·vue.js·学习·ajax·vue·vue3
凤年徐1 小时前
【数据结构与算法】21.合并两个有序链表(LeetCode)
c语言·数据结构·c++·笔记·算法·链表
小一亿2 小时前
【0基础PS】PS工具详解--仿制图章工具
学习·平面·adobe·信息可视化·媒体·photoshop
淮北4945 小时前
STL学习(十一、常用的算数算法和集合算法)
c++·vscode·学习·算法