理解这三种由于并发访问导致的数据读取问题,再理解事务隔离级别就简单多了。
【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前后两次读取到的数据总量应该一致 |