美文网首页Java 程序员Java
大白话讲解脏写、脏读、可重复读和幻读

大白话讲解脏写、脏读、可重复读和幻读

作者: 程序花生 | 来源:发表于2021-04-24 16:21 被阅读0次

    前言

    当多个事务并发执行的时候,会导致什么问题?

    我们知道,执行sql是在buffer pool中对数据进行查询或者修改。如若多个事务同时更新一行数据会出现什么问题?

    1. 脏写

    当事务A和事务B同时去更新同一行数据时,事务A先更新,事务B后更新。

    那么此时,undo log就会记录了事务A所改数据的旧值,假设旧值为 null。随后事务B也对该行数据进行了更新,覆盖掉A更新的值。此时事务A突然发生回滚,那么就会根据它的undo log进行回滚。

    事务A进行了回滚,那么该数据的值就变成了更新前的null值。

    然而,事务B并不知道此事,发现自己更新的值没有了。这就是 脏写

    本质上,就是一个事务修改了另外一个没提交的事务的值(没提交有可能回滚),而导致有可能数据前后不一致的问题。

    2. 脏读

    同样有事务A和事务B。事务A去更新了一行数据,事务B刚好查询到了该行数据,此时事务B拿到的值为A更新的值。

    事务B拿到值后便去业务系统进行各种业务逻辑处理等等,这时,事务A突然回滚了,又把undo log的值回滚到该行数据。紧接着事务B再次查询该行数据的时候,发现前后的值不一样。这就是脏读

    本质上,就是一个事务查询到了另个一个未提交的事务的值,而导致有可能数据前后不一致的问题。

    3. 不可重复读

    在避免脏读的前提下,还有可能出现的不可重复读

    这类情况是在什么场景下发生的呢?

    假设,有一个前提,事务B在更新某行数据,但暂未提交,在未提交事务的时间里,事务A是读不到该行数据的。必须等事务B提交了,事务A才能读取到它修改的值。这样就可以避免脏读。

    这时,假设事务A第一次查询到的值为A值。

    事务B把该行数据的值改为B值并立即提交事务。而事务A尚未提交事务,在事务执行期间进行第二次查询,所以事务A第二次查询到的值为B值。

    紧接着事务C再次更新数据为C值,并提交了事务。此时,事务A在未提交事务的情况下,进行第三次查询,查到的值为C。

    图 3-3

    不可重复读就是以上这种情况,事务A未提交事务,每次读到的数据可能都不一样。

    通过以上分析,那可重复读,就很好理解了。即希望,事务A每次读到的值都是A值。

    4. 幻读

    假设事务A需要多次批量查询数据,第一次查询到了十条数据

    此时事务B往表里插入了几条数据,且B提交了事务,那么此时,就会多出几行数据

    接着事务A再次进行查询时,由于事务B的提交,导致事务A查询多出来了几条数据

    这样就出现了和查询第一次没见到的数据,就是幻读

    本质上,就是一个事务用一样的sql进行多次查询,每次查询到没见过的数据。

    作者:Colors
    链接:https://juejin.cn/post/6954535074637283358
    来源:掘金

    相关文章

      网友评论

        本文标题:大白话讲解脏写、脏读、可重复读和幻读

        本文链接:https://www.haomeiwen.com/subject/rkllrltx.html