Skip to main content

隔离级别

David LiuAbout 2 min

隔离级别

目的:解决并发事务问题

事务隔离级别

  • RU:事务提交前,就可被其他事务读取到

  • RC:事务提交后,才能被其他事务读取到

  • RR:

    InnoDB 在 RR 下利用 Read View 和锁很大程度上解决了幻读问题

  • Serializable:

    Serialized 把幻读解决了

截屏2023-03-04 12.49.05

从上往下安全性越来越好,性能越来越低

  • MySQL 默认 RR
  • oracle, SQL server 默认 RC

设置

-- 查看事务隔离级别
select @@transaction_isolation;

-- 设置事务隔离级别
set [session|global] transaction isolation level {read uncommitted | read commited | ...}

InnoDB RR 级别下避免幻读的方式

MySQL InnoDB 引擎的默认隔离级别虽然是「可重复读」,但是它很大程度上避免幻读现象(并不是完全解决了,解决的方案有两种:

  • 针对快照读(普通 select 语句),是通过 MVCC 方式解决了幻读,因为可重复读隔离级别下,事务执行过程中看到的数据,一直跟这个事务启动时看到的数据是一致的,即使中途有其他事务插入了一条数据,是查询不出来这条数据的,所以就很好了避免幻读问题。
  • 针对当前读(select ... for update 等语句),是通过 next-key lock(记录锁+间隙锁)方式解决了幻读,因为当执行 select ... for update 语句的时候,会加上 next-key lock,如果有其他事务在 next-key lock 锁范围内插入了一条记录,那么这个插入语句就会被阻塞,无法成功插入,所以就很好了避免幻读问题。

解决幻读的方式

解决幻读的方式有很多,但是它们的核心思想就是一个事务在操作某张表数据的时候,另外一个事务不允许新增或者删除这张表中的数据了。解决幻读的方式主要有以下几种:

  1. 将事务隔离级别调整为 SERIALIZABLE
  2. 在可重复读的事务级别下,给事务操作的这张表添加表锁。
  3. 在可重复读的事务级别下,给事务操作的这张表添加 Next-key Lock(Record Lock+Gap Lock)

InnoDB RR 级别下出现幻读的情况