一、简介
本文将总结脏读、不可重复读、幻读的概念以及一些区别,希望通过这些比较能够帮助小伙伴们加深对脏读、不可重复读、幻读的理解。
二、脏读
- 脏读: 指一个事务中访问到了另外一个事务未提交的数据(通俗地讲就是一个事务正在更新数据但是还没有提交更改到数据库,而此时另外一个事务刚好读取到该数据并且使用了这个数据)
简单分析:
- 假设两个线程操作之前数据库里面user_id = 1 对应的age的值为10 ;
- 线程2先更新age的值为20,但是还没有进行commit,在线程2提交之前,线程1读取到了age的值,如果存在脏读,则线程1读取到的age是20而不是10,虽然线程2并没有提交到数据库;
- 如果线程2执行了commit操作,那么线程1虽然在线程2还没提交之前就读取到了修改之后的age = 20,这个时候并没有什么影响;
- 但是如果线程1读取到线程2还没提交的数据后,线程2执行了rollback回滚操作,即没有把修改及时更新到数据库中,而此时线程1使用到了修改后的age = 20,此时就出现错误,读取到了脏数据;
三、不可重复读
- 不可重复读:在一个事务内两次读到的数据不一样(通俗地讲,就是使用想相同的的条件进行查询 , 第一个事务读取过的数据 , 再次读取出来发现值不一样了,原因就是在两次查询的区间内,有另外一个事务将该数据更改了)
简要分析:
- 假设两个线程操作之前数据库里面user_id = 1 对应的age的值为10;
- 线程1首先查询user_id = 1的age值为10;
- 线程2修改age=20,并且执行commit操作;
- 线程1再次查询user_id的age,如果出现不可重复读,那么线程1查询出来的age是20,注意,线程1还没进行commit,两次查询都在同一个事务内;
四、幻读
- 幻读:一个事务读取2次,得到的记录条数不一致(通俗地讲,就是使用相同的条件进行两次查询 , 第 1次查询和第 2次查询读出来的记录数不一样,原因就是另外一个事务新增或者删除了第一个事务结果集里面的数据)
- 举例:同一个事务内第一次查询时候有n条记录,第二次使用相同的条件查询却变成了n+1条记录,这就好像产生了幻觉,两次查询数据记录条数不一致。
简要分析:
- 假设两个线程操作之前数据库里面user_id > 1 对应的数据只有一条;
- 线程1首先查询user_id > 1的记录条数为1;
- 线程2执行插入、或者删除操作,并且执行commit操作;
- 线程1再次查询user_id > 1的返回的记录条数为2了,在线程1的同一个事务内,就好像发生了幻觉,两次查询的记录条数不一致;
五、总结
不可重复读的重点是修改:相同的查询条件,第一次读取的数据,再次读取出来结果不一致;
幻读的重点在于新增或者删除: 相同的查询条件,第 1 次和第 2 次读出来的记录数不一样;
以上就是关于脏读、不可重复读、幻读的总结,希望对小伙伴们有所帮助。今天是2019年最后一天呀,在这里先祝小伙伴们新年快乐,家庭和睦,新的一年,希望一直努力坚持学习下去!