跳到主要内容
极客日志极客日志面向AI+效率的开发者社区
首页博客我的书AI学习GitHub 精选镜像AI 生图工具UI配色美学关于
搜索内容 / 工具 / 仓库 / 镜像...⌘K搜索
注册
博客列表
SQL

理解MySQL事务隔离:读未提交、读提交、可重复读和串行化

MySQL 事务并发时,隔离性决定了事务间数据的可见程度。标准定义了四种隔离级别:读未提交会导致脏读,读提交避免脏读但可能不可重复读,可重复读是 MySQL 默认级别能防止不可重复读,串行化则完全串行执行。通过实例说明了脏读和不可重复读的现象及影响,并介绍了如何查看和设置隔离级别。实际使用需在性能和数据一致性间权衡。

漫步发布于 2026/6/30更新于 2026/10/2067 浏览
理解MySQL事务隔离:读未提交、读提交、可重复读和串行化

理解MySQL事务隔离

在实际开发中,MySQL 服务往往被多个客户端同时访问,这些访问通常以事务的形式进行。一个事务可能包含多条 SQL,原子性要求让用户要么看到执行前的状态,要么看到执行后的状态。当多个事务并发执行时,它们可能会互相影响,比如同时操作同一张表甚至同一行数据。为了让事务执行过程中尽量不受干扰,数据库引入了隔离性。而允许事务受到不同程度的干扰,就对应了不同的隔离级别。

这就好比试衣服:进试衣间需要完全隔离,而试鞋子可能就不需要那么严格的隔离。

事务隔离示意图

四种隔离级别

标准定义了四种隔离级别,按隔离程度由低到高:

  • 读未提交(Read Uncommitted):所有事务都能看到其他事务未提交的修改。这相当于几乎没有隔离,生产环境基本不用。
  • 读提交(Read Committed):一个事务提交后,另一个事务才能看到它的修改。但这会导致同一个事务内多次读取同一数据可能得到不同的值,即不可重复读。
  • 可重复读(Repeatable Read):MySQL 的默认级别。事务执行过程中看到的数据与事务开始时一致,其他事务的提交对当前事务不可见,只有都结束并重新启动后才能看到新结果。
  • 串行化(Serializable):最高的隔离级别,事务一个接一个串行执行,效率最低但最安全。

隔离大多通过锁机制实现,不同级别使用的锁策略也不同。注意这几种级别主要针对读写并发,读读场景通常还是串行化处理。

如何查看和设置隔离级别

隔离级别可以在会话(Session)或全局(Global)级别设置。会话级只影响当前连接,全局级影响所有新连接(已存在的连接需重新登录才生效)。

查看当前隔离级别:

-- 查看会话级
SELECT @@session.tx_isolation;

-- 查看全局级
SELECT @@global.tx_isolation;

-- 简写,效果同上
SELECT @@tx_isolation;

设置语法:

SET [SESSION|GLOBAL] TRANSACTION ISOLATION LEVEL 
{READ UNCOMMITTED | READ COMMITTED | REPEATABLE READ | SERIALIZABLE};

例如,把当前会话设为串行化:

SET SESSION TRANSACTION ISOLATION LEVEL SERIALIZABLE;

-- 验证
SELECT @@global.tx_isolation;   -- 可能仍是 REPEATABLE-READ
SELECT @@session.tx_isolation;  -- 应输出 SERIALIZABLE

设置全局为读未提交:

SET GLOBAL TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;

SELECT @@global.tx_isolation;   -- 输出 READ-UNCOMMITTED

如果没有立即生效,一般关闭客户端重连一下就好。

脏读与不可重复读实例

读未提交下的脏读

在读未提交级别,一个事务能读到另一个事务还未提交的更新。不加锁保护,效率高但数据一致性极差,强烈不建议使用。

打开两个终端,先确保隔离级别设为此级别。

-- 终端 A
SET GLOBAL TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
-- 重连后验证
SELECT @@tx_isolation;

然后终端 A 开启事务但暂不提交:

BEGIN;
UPDATE account SET blance = 123.0 WHERE id = 1;
-- 没有 COMMIT

终端 B 在另一个事务里查询:

BEGIN;
SELECT * FROM account;
-- 此时会读到终端 A 未提交的 123.00,这就是脏读

读提交下的不可重复读

切换到读提交级别:

-- 终端 A
SET GLOBAL TRANSACTION ISOLATION LEVEL READ COMMITTED;
-- 重连验证

终端 A 开启事务更新数据:

BEGIN;
UPDATE account SET blance = 321.0 WHERE id = 1;
-- 尚未提交

终端 B 第一次查询:

BEGIN;
SELECT * FROM account;
-- 此时读到旧值

终端 A 提交:

COMMIT;

终端 B 再次查询:

SELECT * FROM account;
-- 这次读到了 321.0,同一个事务里两次读取结果不同,即不可重复读。

这个不一致会带来实际问题。 比如小王负责把 Tom 的工资从 3200 改到 4500,小张负责根据工资发奖品。小张第一次查询看到 3200(符合发奖条件),但还没处理完,小王提交了更新,小张第二次查询看到 4500(不符合条件),导致业务判断出错。这种同一事务内的数据波动,往往是业务逻辑的 bug 源头。

因此,虽然读提交比读未提交看起来'高级'一些,但不可重复读的问题让它很少直接用于生产,除非业务明确能容忍这类不一致。大多数情况下,我们还是会用可重复读甚至串行化来保障数据稳定性。

选择隔离级别需要在并发性能和数据一致性之间做出权衡,没有绝对完美的方案。

目录

  1. 理解MySQL事务隔离
  2. 四种隔离级别
  3. 如何查看和设置隔离级别
  4. 脏读与不可重复读实例
  5. 读未提交下的脏读
  6. 读提交下的不可重复读

更多推荐文章

查看全部
  • Java 核心基础:数据类型、运算符与方法详解
  • 基于 KerasCV 的 Stable Diffusion 高性能文生图实现
  • 医疗 AI 新范式:数理模型重构传统大模型
  • MySQL 库级别 DDL 操作详解:创建、修改与删除
  • 人工智能应用工程师(高级):全栈技能体系与实战路径
  • C++ 模板的两大核心特性:typename 与分离编译
  • ROS2 在 RViz 中可视化 URDF 机器人模型
  • 基于深度学习与强化学习融合的逆变器系统:联邦学习支持的分布式协同控制建模
  • 基于 SpringBoot+Vue 的汽车资讯网站管理系统设计与实现
  • DSP + FPGA 控制步进电机原理与代码实现
  • Naiz AI:从语义到像素,全链路重构视频数字孪生
  • LLM 推理中处理超出上下文长度的外推方法
  • Python 包管理工具 uv 使用指南
  • 2026 值得关注的开源低代码与零代码平台推荐
  • 基于阿里云ASR的AI电销机器人源码解析与部署指南
  • Java 零基础入门指南:环境配置与核心语法
  • 电科金仓 KES V9 2025:融合 AI 与多模态数据库技术解析
  • 大模型 RAG 与微调(Fine-Tune)的性能提升选择策略
  • Web3.0 时代域名的商业价值重构与落地路径
  • C++ 核心面试题总结:语法、内存与类特性详解

相关免费在线工具

  • SQL 美化和格式化

    在线格式化和美化您的 SQL 查询(它支持各种 SQL 方言)。 在线工具,SQL 美化和格式化在线工具,online

  • SQL转CSV/JSON/XML

    解析 INSERT 等受限 SQL,导出为 CSV、JSON、XML、YAML、HTML 表格(见页内语法说明)。 在线工具,SQL转CSV/JSON/XML在线工具,online

  • CSV 工具包

    CSV 与 JSON/XML/HTML/TSV/SQL 等互转,单页多 Tab。 在线工具,CSV 工具包在线工具,online

  • Base64 字符串编码/解码

    将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online

  • Base64 文件转换器

    将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online

  • Markdown转HTML

    将 Markdown(GFM)转为 HTML 片段,浏览器内 marked 解析;与 HTML转Markdown 互为补充。 在线工具,Markdown转HTML在线工具,online