MySQL事务隔离级别
  1. 什么是脏读: 读到没有commit的数据

  2. 什么是不可重复读:同一个事务中,两次读取到的数据不一样。

  3. 什么是幻读同一个事务中,两次读取到的数据不一样。这个流程看起来和不可重复读差不多,但幻读强调的集合的增减,而不是单独一条数据的修改。最常见的场景便是

事务的隔离级别

1
select @@global.tx_isolation;

级别逐级别提高,越高数据隔离的越彻底。可是代价是付出性能。

  • value 为0

    读未提交(Read Uncommitted),在这个级别下,所有事务都能看到其他未提交的事务的数据,基本很少用到。

  • value 为1

    一个事务只能看见已经提交事务所做的改变。解决脏读的问题,存在不可重复读,幻读的问题。

  • 可重复读 REPEATABLE-READ | 2

    MySQL默认的级别,解决脏读,不可重复读。但是存在幻读的。接下来就是要讨论如何避免了。

  • 序列化 SERIALIZABLE | 3

    强迫事务排序,串行执行事务,从而杜绝上面的所有问题,但是会带来大量的等待,基本没有使用。

在RR(READTABLE-READ)级别下,如何避免幻读,答案是显式加锁。

简单的场景:

A 事务:查询表是否存在id=10000,如果无,就插入数据。

就在插入的前一刻,另外一个事务插入了id=10000的数据,此刻A事务就会莫名收到数据已经存在的错误,也无法插入成功。这就是典型的幻读了。如何解决呢,用SELECT FOR UPDATE,无论数据是否存在,都会被加上锁。(当记录不存在的时候,mysql 会给索引加上gap间隙锁,对此可以模拟一下哦)

Author: Chandler Kwok
Link: http://yoursite.com/2020/04/13/mysql%E4%BA%8B%E5%8A%A1/
Copyright Notice: All articles in this blog are licensed under CC BY-NC-SA 4.0 unless stating additionally.