面试官:谈一下对MySQL事务隔离的理解

什么是事务隔离?

隔离是什么?看到"隔离"这个字眼,估计大部分人的第一反应就是"WC,阳了",那么"隔离你"就是为了保证其他人的安全。

MySQL中的事务隔离也是这样的,主要是为了确保在并发事务执行时,各个事务之间能够相互独立、互不干扰地运行,从而保证数据的一致性。

事务的隔离级别

MySQL事务隔离为了满足不同场景,提供了4个事务隔离级别(严格来讲是InnoDB存储引擎支持的),分别是:

  • 读未提交(Read Uncommitted)
  • 读已提交(Read Committed)
  • 可重复读(Repeatable Read)
  • 串行化(Serializable)

读未提交

读未提交,很好理解:事务在各自的周期内,可以读取到其他事务未提交的数据。

以下图为例,事务2的两次查询结果分别为18和19,即便事务1没有提交。

这种现象被称为"脏读"。

读已提交

读已提交,很好理解:事务在各自的周期内,每次对同一个sql进行查询都是已经提交的数据。

以下图为例,事务2的两次查询结果分别为18和19,因为在此期间事务1对数据进行了更改。

但是,这种现象被称为"不可重复读",因为违反了事务的隔离性原则(在一个事务内,数据应该是一致的)

个人认为,在大部分情况下,可以读到已经提交过的数据,就不算是一个问题(MySQL默认的隔离级别也是这个)。

可重复读

可重复读,这样理解:既然有"不可重复读"的现象,那我满足你,让你可以重复读。

即:每个事务在自己的事务周期内,多次对同一个sql进行查询都是相同的数据。

以下图为例,事务2的两次查询结果都一样,即便在此期间事务1对数据进行了更改。

但是,如果在"可重复读 "级别下进行了当前读 ,那么还是会出现像"读已提交"中出现的"不可重复读"的现象,不过这里称之为"幻读"(叫法真多)。

这里说下什么是当前读。

顾名思义,当前读就是读取行数据当前最新的状态,这个过程中会对所有读、写的数据加上相应的读锁、写锁、范围锁,目的是避免并发冲突。在MySQL中使用以下sql语句都属于当前读:

sql 复制代码
UPDATE ...
sql 复制代码
DELETE ...
sql 复制代码
INSERT ...
sql 复制代码
SELECT ... LOCK IN SHARE MODE
sql 复制代码
SELECT ... FOR UPDATE

可能会有人问:UPDATEDELETEINSERT为什么是读操作?

《MySQL是如何保证数据不丢失的?》中有介绍过,在执行DML操作时,会先根据条件去查询相应的行数据,所以也存在读操作。

与当前读对应的还有快照读。快照读是一种不加锁的查询,目的是为了提高并发性能。(具体实现原理,将在后续文章中为您揭晓)

普通的SELECT语句,都属于快照读,只不过不同的隔离级别快照的时机不同。

串行化

可串行化,很好理解:并发事务的执行完全是串行,依次执行,不存在冲突导致的一致性问题。但是可想而知,这种隔离级别的并发效率肯定极为低下。

总结

MySQL提供了多种事务隔离级别,包括读未提交、读已提交、可重复读和串行化等。这些隔离级别在并发性能和数据一致性之间提供了不同的权衡,可以根据具体的应用场景和需求来选择适合的隔离级别。

相关推荐
小码哥_常5 小时前
Spring Boot 牵手Spring AI,玩转DeepSeek大模型
后端
0xDevNull5 小时前
Java反射机制深度解析:从原理到实战
java·开发语言·后端
数据库小组5 小时前
2026 年,MySQL 到 SelectDB 同步为何更关注实时、可观测与可校验?
数据库·mysql·数据库管理工具·数据同步·ninedata·selectdb·迁移工具
华洛6 小时前
我用AI做了一个48秒的真人精品漫剧,不难也不贵
前端·javascript·后端
WZTTMoon6 小时前
Spring Boot 中Servlet、Filter、Listener 四种注册方式全解析
spring boot·后端·servlet
SHoM SSER6 小时前
MySQL 数据库连接池爆满问题排查与解决
android·数据库·mysql
standovon6 小时前
Spring Boot整合Redisson的两种方式
java·spring boot·后端
Cosolar7 小时前
LlamaIndex RAG 本地部署+API服务,快速搭建一个知识库检索助手
后端·openai·ai编程
qq_283720057 小时前
MySQL技巧(十四): 连接数过多 (Too many connections):原因 + 排查 + 终极解决方案
mysql·连接池·性能·异常
MX_93597 小时前
SpringMVC请求参数
java·后端·spring·servlet·apache