本文已参与「新人创作礼」活动, 一起开启掘金创作之路。
快照读和当前读的区别
当前读和快照读。顾名思义,当前读就是读的是当前时刻已提交的数据,快照读就是读的是快照生成时候的数据。
这里概念理解要抛开读出跟写入的物理概念、读写分离的概念等等。这里的读包含了SELECT、UPDATE、INSERT等语句中的处理逻辑,其实就是视图的逻辑概念。
当前时刻很好理解。执行语句的时刻,库里(磁盘+buffer)是什么样子就是什么样子
快照读
又叫一致性读,读取的是快照数据。不加锁的简单的 SELECT 都属于快照读,即不加锁的非阻塞 读;比如这样: 之所以出现快照读的情况,是基于提高并发性能的考虑,快照读的实现是基于MVCC,它在很多情况下, 避免了加锁操作,降低了开销。 既然是基于多版本,那么快照读可能读到的并不一定是数据的最新版本,而有可能是之前的历史版本。 快照读的前提是隔离级别不是串行级别,串行级别下的快照读会退化成当前读。
当前读
当前读读取的是记录的最新版本(最新数据,而不是历史版本的数据),读取时还要保证其他并发事务 不能修改当前记录,会对读取的记录进行加锁。加锁的 SELECT,或者对数据进行增删改都会进行当前读。
比如:
SELECT * FROM player WHERE ... SELECT * FROM student LOCK IN SHARE MODE; # 共享锁 SELECT * FROM student FOR UPDATE; # 排他锁 INSERT INTO student values ... # 排他锁 DELETE FROM student WHERE ... # 排他锁 UPDATE student SET ... # 排他锁
怎么知道执行的语句是当前读还是快照读?
1.在默认隔离级别下,select 语句默认是快照读 select a from t where id = 11
2.select 语句加锁是当前读
共享锁
select a from t where id = 1 lock in share mode;
#排他锁
select a from t where id = 1 for update;
3.update 语句是当前读
update t set a = a + 1;