菜鸟日记01------MySQL之脏读、不可重复读、幻读
脏读
是指当前事务读取到其他事务未提交的数据
例子:有事务a,b和一条记录 id为1,name为张三的数据。
1、b首先进行更新操作,将name的值由张三改为李四,但是未提交事务
2、然后a进行查询操作,查询姓名为李四
然后a就懵逼了,我TM读取的是李四,但是你现在在数据库中却TM给我存储的是张三,我TM到底要用哪个?
这就是脏读-----事务a读取到事务b未提交的数据
不可重复读
是指同一事务中前后查询不一致的问题
例子:
a先查询了一条记录,name为张三
1 select name from stu where id = 1
然后b执行了更新,并且还提交了

a再次按相同条件进行查询,name为李四
1 select name from stu where id = 1
a就会出现懵逼,同样的查询语句,两次得到的执行结果却不一样。
其实在并发条件下,假如两条select语句间有另外一个事务对name执行了update操作还提交了,把张三的这个值改成了李四,a再次执行同样查询导致name由张三变为李四
a这时候就有意见了,我TM明明没有对name进行修改,可是为什么会变成李四?谁TM改我数据了。
这就是不可重复读:同一事务中前后查询不一致
会导致程序运行变得不可预期、不可控
幻读
是指一次事务中前后数据量发生变化,用户产生不可预料的问题
分类:1、并发删除 2、并发插入
1、并发插入
a先查询一条记录,name为张三
1 select name from stu where id = 1
b插入了一条数据,name为李四
1 insert into stu(name)values('李四')
当a再次按相同条件查询
1 select name from stu where id = 1
结果多了一条李四的记录,然后a懵逼了,将才明明只有一条一条记录,怎么突然多出来了 一条,感觉出现了幻觉
2、并发删除
a先查询一条记录,name为张三
1 select name from stu where id = 1
b删除了这条数据
1 delete from stu where id =1
然后a在再次执行相同条件查询的时候,就会懵逼,怎么张三的记录消失了呢,将才还在呢,怎么TM又没了,再此出现幻觉
这就是幻读----一次事务中前后数据量发生变化,用户产生了不可预料的问题
总结:
1、事务a读取某一个范围的数据,第二次读取同样范围的数据,记录数发生变化(增多或减少)即为幻读
2、select 读取的数据的方式是快照读,update读取的数据方式是当前读,即其他事务更新/新增/删除的数据都会被读取到并进行了更新
不同点:
1、不可重复读 的重点是修改,幻读 的重点在于插入或者删除
2、虽然不可重复读和幻读都是读取另外一个提交的事务,但是,不可重复读查询的是同一个数据项,幻读针对的是一批数据整体(个数)
3、从控制的角度出发
不可重复读只需锁住满足条件的记录即可
幻读不光需要锁住满足条件的记录还需锁住其相近的记录
解决方法:
要解决以上问题,需要用到 事务的隔离级别
1、脏读 ----> 禁止写时读,避免了‘脏读’,对应隔离级别 read committed(读已提交)
2、不可重复读 ----->紧张读时写,避免了‘不可重复读’,对应隔离级别 repeatable read(可重复读)
3、幻读 ---->要把整个表给锁住,需要使用到serialize
当然,隔离级别越高,并行度越低,付出的代价就越大
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 百万级群聊的设计实践
· WPF到Web的无缝过渡:英雄联盟客户端的OpenSilver迁移实战
· 永远不要相信用户的输入:从 SQL 注入攻防看输入验证的重要性
· 全网最简单!3分钟用满血DeepSeek R1开发一款AI智能客服,零代码轻松接入微信、公众号、小程
· .NET 10 首个预览版发布,跨平台开发与性能全面提升