数据库隔离级别

105 阅读2分钟

首先再讲数据库隔离级别时,我们要明白并行事务会引发什么问题?

并行事务引发问题

它会引发:

  • 脏读:读到其他事务未提交的数据;
  • 不可重复读:前后读取的数据不一致;
  • 幻读:前后读取的记录数量不一致。

严重性从上到下依次递减

对此解决的隔离级别

那么有问题自然希望有隔离级别去规避这些现象,但是隔离级别越高,性能效率就会越低。四个隔离级别如下:

  • 读未提交: 指一个事务还没提交,它做的变更就能被其他事务看到
  • 读提交: 指一个事务提交之后,它做的变更才能被其他事务看到(read view实现的)
  • 可重复读: 指一个事务执行过程中看到的数据,一直跟这个事务启动时看到的数据是一致的(read view实现的)
  • 串行化: 会对记录加上读写锁,在多个事务对这条记录进行读写操作时,如果发生了读写冲突的时候,后访问的事务必须等前一个事务执行完成,才能继续执行(通过加锁来避免并行访问)

image.png

MySQL InnoDB 引擎的默认隔离级别虽然是「可重复读」,但是它很大程度上避免幻读现象,为什么呢?我们简略地谈谈:

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