mysql事务隔离级别/脏读/不可重复读/幻读详解
一、四种事务隔离级别
1.1 read uncommitted 读未提交
即:事务A可以读取到事务B已修改但未提交的数据。
除非是文章阅读量,每次+1这种无关痛痒的场景,一般业务系统没有人会使用该事务隔离级别,标准实在太宽松了。
1.2 read committed 读已提交(简称RC)
即:事务A只能读取到事务B修改并已提交的数据。
这个级别相对要严格一些,至少是要等其它事务把变更提交到db,才能读取到,听上去蛮靠谱的。但是有些业务场景,比如会员系统中,如果要在一个事务中,多次读取用户身份,判断是否会员,如果刚开始读取到该用户是会员,做了一些逻辑处理,后面又读到用户不是会员了,这就有点崩溃,不知道如何继续。这种希望同1个事务中,关键数据不管读取多次次,结果都一样,RC级别就不行了。
1.3 repeatable read 可重复读
即:同一个事务中,多次读取某一行记录,始终是一样的值,不管在此期间,其它事务有没有修改过该数据(不论是否提交)。该级别解决了RC不可重复读的问题,但是存在幻读问题(幻读后面会详解)。
1.4 serializable 串行化
即:一个事务在修改其它数据时,如果有其它事务也想改,必须等前面的事务提交或回滚后,才能继续。最严格的级别,但是性能最低,也几乎没人用。
二、脏读/不可重复读/幻读
2.1 脏读

验证:
a. 找一个mysql环境,建一个测试表t_people,就2列 id ,name
b. 开二个mysql终端,连到db上,为方便讲解,这2个终端称为“终端1”、“终端2”,终端1里输入:
set session transaction isolation level read uncommitted;
start transaction;
即:设置当前会话的隔离级别为"读未提交"。

终端2里,输入:
start transaction;
update t_people set name='xxx' where id=1;

然后再回到“终端1”,执行
select id,name from t_people where id=1;

可以看到,读取到了未提交的脏数据 。 终端2里,此时如果执行rollback回滚

终端1里,继续执行
select id,name from t_people where id=1;

可以发现最新结果,已经是回滚后的数据。很显然:如果有脏读问题出现,就更加保证不了“可重复读”。
2.2 不可重复读

将事务隔离级别设置成read committed(即:读已提交),可解决脏读问题,但满足不了“可重复读需求”。
验证方法跟刚才类似,终端1里输入:
set session transaction isolation level read committed;
将级别设置成RC,然后2个终端里都开启事务,终端2中,修改一行数据,但是不提交,此时终端1里应该是读不到终端2修改的数据。然后终端2提交,终端1才能读到修改后的数据。终端2如果继续修改、提交,终端1里再读取这1行,将是最新的值。(也就是只说,只要终端2不断修改,不断提交,终端1里就能读到这行不同的新值,即:保证不了同1个事务中,同一行数据,多次重复读取的值不变)
2.3 幻读
将隔离级别继续调整至Repeatable Read,还是刚才的场景,变成这样:

事务A对于同一行数据,不管读多少次,始终是相同的值,完全不理会有没有其它事务在修改它。有点:“两耳不闻窗外事,一心只读圣贤书”的味道。但是这也有问题,比如秒杀订单系统中,事务A第1次读取商品库存,发现还有1个,可以下单,赶紧继续,但是此时,可能有另一个事务,也在下单,已经提交了订单,把库存减为0了,事务A并不知道,因为多次读取库存的值是一样的,还是1,最后仍然把订单创建了,形成超卖。
验证方法:
set session transaction isolation level repeatable read;
剩下的步骤跟前面类似,就不重复赘述了。
2.4 串行化
从db层面,要想同时解决脏读、不可重复读、幻读,只有串行化这个级别可以做到。
set session transaction isolation level serializable;
如下图:终端1设置串行化后,紧接着select xxx where id=1这条语句后,id=1的这行记录,就被锁了。

在终端2里,更新其它记录(即:id不等于1)可以正常成功,但是更新id=1 时,就会卡住,除非终端1把事务提交或回滚,否则将一直卡着,直到超时失败。

小结:
| 隔离级别 | 存在的问题 |
| 读未提交 | 脏读、不可重复读、幻读 |
| 读已提交 | 不可重复读、幻读 |
| 可重复读 | 幻读 |
| 串行化 | 性能问题 |
隔离级别越严格,db综合性能越低。
建议:
大多数情况下,RC(读已提交)基本上就足够了,如果并发度高,可以考虑“RC级别+(应用层)分布式锁”,这样即能保证数据正确,对db的性能压力也较低。
mysql事务隔离级别/脏读/不可重复读/幻读详解的更多相关文章
- 数据库事务隔离级别 - 分析脏读 & 不可重复读 & 幻读
一 数据库事务的隔离级别 数据库事务的隔离级别有4个,由低到高依次为Read uncommitted .Read committed .Repeatable read .Serializable ,这 ...
- Java -- JDBC 事务处理, 事务的隔离级别 脏读 不可重复读 等...
1. 事务指逻辑上的一组操作,组成这组操作的各个单元,要不全部成功,要不全部不成功. 数据库开启事务命令 •start transaction 开启事务 •Rollback 回滚事务 •Commit ...
- MySQL事务隔离级别测试实例
https://www.cnblogs.com/huanongying/p/7021555.html MySQL事务隔离级别 事务隔离级别 脏读 不可重复读 幻读 读未提交(read-uncommit ...
- 在?MySQL事务隔离级别了解一下?
事务的四大ACID 属性:Atomicity 原子性.Consistency 一致性.Isolation 隔离性.Durability 持久性. 原子性: 事务是最小的执行单位不可分割,强调事务的不可 ...
- MySQL事务隔离级别(一)
本文实验的测试环境:Windows 10+cmd+MySQL5.6.36+InnoDB 一.事务的基本要素(ACID) 1.原子性(Atomicity):事务开始后所有操作,要么全部做完,要么全部不做 ...
- 面试突击61:说一下MySQL事务隔离级别?
MySQL 事务隔离级别是为了解决并发事务互相干扰的问题的,MySQL 事务隔离级别总共有以下 4 种: READ UNCOMMITTED:读未提交. READ COMMITTED:读已提交. REP ...
- 【原创】新说Mysql事务隔离级别
引言 大家在面试中一定碰到过 说说事务的隔离级别吧? 老实说,事务隔离级别这个问题,无论是校招还是社招,面试官都爱问!然而目前网上很多文章,说句实在话啊,我看了后我都怀疑作者弄懂没!因为他们对可重复读 ...
- 五分钟后,你将真正理解MySQL事务隔离级别!
什么是事务? 事务是一组原子性的SQL操作,所有操作必须全部成功完成,如果其中有任何一个操作因为崩溃或其他原因无法执行,那么所有的操作都不会被执行.也就是说,事务内的操作,要么全部执行成功,要么全部执 ...
- 一文讲清楚MySQL事务隔离级别和实现原理,开发人员必备知识点
经常提到数据库的事务,那你知道数据库还有事务隔离的说法吗,事务隔离还有隔离级别,那什么是事务隔离,隔离级别又是什么呢?本文就帮大家梳理一下. MySQL 事务 本文所说的 MySQL 事务都是指在 I ...
- 【转】新说Mysql事务隔离级别
作者:孤独烟 转自:https://www.cnblogs.com/rjzheng/p/9955395.html 引言 大家在面试中一定碰到过 说说事务的隔离级别吧? 老实说,事务隔离级别这个问题,无 ...
随机推荐
- 时间工具之“js初始化当前时间数据”
⑨前端:初始化当前时间数据 方案一(峰哥认可) // 2023-02this.$moment().format('yyyy-MM'),// 2023-02-02this.$moment().form ...
- vue3 基础-事件绑定 & 修饰符
无非就是 js 的一些 事件, 按键, 鼠标 等的一些绑定在 vue 的实现而已, 很好理解. 先来看一个基础例子. 事件初体验 <!DOCTYPE html> <html lang ...
- FastAPI与Alembic:数据库迁移的隐秘艺术
title: FastAPI与Alembic:数据库迁移的隐秘艺术 date: 2025/05/13 02:02:31 updated: 2025/05/13 02:02:31 author: cmd ...
- 解决每次git pull/push都需要输入用户账号密码的方法
如果我们git clone的下载代码的时候是连接的https://而不是git@git (ssh)的形式,当我们操作git pull/push到远程的时候,总是提示我们输入账号和密码才能操作成功,频繁 ...
- arcgis创建sqlserver企业级空间数据库过程中出现的问题及解决方案
在arcgis中创建sqlserver版本的企业空间数据库过程中,出现了多种问题,现把问题的现象.原因和解决方案记录下来,以防遗忘(年纪大了). 1 用sa账号创建空间数据库提示创建失败15456 安 ...
- [极客大挑战 2019]FinalSQL 1
[极客大挑战 2019]FinalSQL 1 这篇主要是考察布尔盲注,而且他很贼,弄了两个输入框,但过滤的东西很多:真正的注入点在search.php传入的参数.说来惭愧,之前就做过布尔盲注的题目,结 ...
- C# Task 取消执行的简单封装
我让DeepSeek帮我写了一段使用 CancellationTokenSource 取消任务的简单示例如下: 取消任务的简单示例 using System.Threading.Tasks; usin ...
- js判断一个变量是否存在值得简单方法
在编码过程中,有时候我们需要对一个变量判断其是否有值,这里有一种比较不错的方法判断: !!variable //返回True为存在值,返回False为不存在值 注意是双感叹号"!!" ...
- WPF实现简易计算器(MVVM、控件自定义样式)
目录 WPF实现简易计算器(MVVM.控件自定义样式) 界面 文件结构 项目代码 WPF实现简易计算器(MVVM.控件自定义样式) 运行环境:VS2022 .Net framework4.8 完整项目 ...
- Form 表单在数栈的应用(上): 校验篇
一.引言 本文为主题即为 Form 表单在数栈的应用,旨在希望能通过一些在数栈已经应用的实例和笔者整理的小tips来帮助大家更深入的理解Form表单校验.以及联动校验的认知和做法. 本文的重点为 ...