隔离级别
January 2, 2023About 2 min
隔离级别
目的:解决并发事务问题
事务隔离级别
RU:事务提交前,就可被其他事务读取到
RC:事务提交后,才能被其他事务读取到
RR:解决不可重复读问题
InnoDB 在 RR 下利用 Read View 和锁很大程度上解决了幻读问题
Serializable:
Serialized 把幻读解决了,但是效率低
从上往下安全性越来越好,性能越来越低
- 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 锁范围内插入了一条记录,那么这个插入语句就会被阻塞,无法成功插入,所以就很好了避免幻读问题。
解决幻读的方式
解决幻读的方式有很多,但是它们的核心思想就是一个事务在操作某张表数据的时候,另外一个事务不允许新增或者删除这张表中的数据了。解决幻读的方式主要有以下几种:
- 将事务隔离级别调整为
SERIALIZABLE
。 - 在可重复读的事务级别下,给事务操作的这张表添加表锁。
- 在可重复读的事务级别下,给事务操作的这张表添加
Next-key Lock(Record Lock+Gap Lock)
。