MENU

(数据库)快速理解脏读、不可重复读、幻读

• March 17, 2020 • Read: 85 • 技术笔记,数据库

快速理解脏读、不可重复读、幻读?

理解这三种由于并发访问导致的数据读取问题,再理解事务隔离级别就简单多了。

(1)脏读(读取未提交数据)

A事务读取B事务尚未提交的数据,此时如果B事务发生错误并执行回滚操作,那么A事务读取到的数据就是脏数据。就好像原本的数据比较干净、纯粹,此时由于B事务更改了它,这个数据变得不再纯粹。这个时候A事务立即读取了这个脏数据,但事务B良心发现,又用回滚把数据恢复成原来干净、纯粹的样子,而事务A却什么都不知道,最终结果就是事务A读取了此次的脏数据,称为脏读。

这种情况常发生于转账与取款操作中

时间顺序转账事务取款事务
1 开始事务
2开始事务
3 查询账户余额为2000元
4 取款1000元,余额被更改为1000元
5查询账户余额为1000元(产生脏读)
6 取款操作发生未知错误,事务回滚,余额变更为2000元
7转入2000元,余额被更改为3000元(脏读的1000+2000)
8提交事务
备注按照正确逻辑,此时账户余额应该为4000元

(2)不可重复读(前后多次读取,数据内容不一致)

事务A在执行读取操作,由整个事务A比较大,前后读取同一条数据需要经历很长的时间 。而在事务A第一次读取数据,比如此时读取了小明的年龄为20岁,事务B执行更改操作,将小明的年龄更改为30岁,此时事务A第二次读取到小明的年龄时,发现其年龄是30岁,和之前的数据不一样了,也就是数据不重复了,系统不可以读取到重复的数据,成为不可重复读。

时间顺序事务A事务B
1开始事务
2第一次查询,小明的年龄为20岁
3 开始事务
4其他操作
5 更改小明的年龄为30岁
6 提交事务
7第二次查询,小明的年龄为30岁
备注按照正确逻辑,事务A前后两次读取到的数据应该一致

(3)幻读(前后多次读取,数据总量不一致)

事务A在执行读取操作,需要两次统计数据的总量,前一次查询数据总量后,此时事务B执行了新增数据的操作并提交后,这个时候事务A读取的数据总量和之前统计的不一样,就像产生了幻觉一样,平白无故的多了几条数据,成为幻读。

时间顺序事务A事务B
1开始事务
2第一次查询,数据总量为100条
3 开始事务
4其他操作
5 新增100条数据
6 提交事务
7第二次查询,数据总量为200条
备注按照正确逻辑,事务A前后两次读取到的数据总量应该一致

不可重复读和幻读到底有什么区别呢?
(1)不可重复读是读取了其他事务更改的数据,针对insert与update操作

解决:使用行级锁,锁定该行,事务A多次读取操作完成后才释放该锁,这个时候才允许其他事务更改刚才的数据。

(2)幻读是读取了其他事务新增的数据,针对insert与delete操作

解决:使用表级锁,锁定整张表,事务A多次读取数据总量之后才释放该锁,这个时候才允许其他事务新增数据。

这里是 原文地址 我认为作者这里写得非常好,故转发一下.

本站所有未注明转载的文章均为原创,并采用CC BY-NV-SA 4.0 授权协议,转载请注明来源。

Archives QR Code
QR Code for this page
Tipping QR Code
Leave a Comment

2 Comments
  1. 那这些问题要尽量避免吧

    1. @风也这一步操作叫做事务管理,在Spring中还是比较好解决的