一、事务隔离级别
mysql支持四种事务隔离级别:
- 读未提交:一个事务可以读取到另一个事务还未提交的数据;
- 读已提交:一个事务可以读取到另一个事务已经提交的数据;
- 可重复读:同一个事务中,无论读取多少次,结果都和第一次读一样;
- 串行化:多个事务之间读写和写写按照间隙锁互斥。
二、事务隔离级别实现原理
2.1 读未提交
直接读取最新的数据就好。
2.2 读已提交和可重复读
读已提交和可重复读,都是通过MVCC进行实现的,两者的区别在于ReadView
生成方式不同。
MVCC的两个重要概念:版本链
和ReadView
。
2.2.1 版本链
在InnoDB引擎中,每行记录都会有两个隐藏列,即trx_id
和roll_pointer
。
- trx_id:记录最近修改该行的事务id;
- roll_pointer:指针,指向该行数据的上一个版本地址。
2.2.2 ReadView
ReadView有四个重要的字段:
- creator_trx_id:创建该RV的事务id;
- m_ids:在创建该RV时,当前数据库活跃事务的id列表,即还没提交的事务id列表;
- min_trx_id:最小的活跃事务id;
- max_trx_id:最大的活跃事务id+1。
2.2.3 ReadView创建区别
在读已提交
时,一个事务中,每次执行select
都会创建一个ReadView
。
在可重复读
时,一个事务中,只在第一次执行select
时,创建一个ReadView
。
2.2.4 ReadView的使用规则
在一个事务中,执行select
只能看到trx_id
在min_trx_id
和max_trx_id
之间的事务。mysql会按照版本链的顺序从最新的记录开始判断,直到当前事务可以看到的记录为止,或者结束为止。
读已提交和可重复读的底层原理均是MVCC,但是,由于两者创建ReadView的时机不同,故出现了两种隔离表现。
2.3 串行化
使用间隙锁
,对读-写和写-写进行互斥。