mysql-快照读 vs 当前读

在 mysql repeatable read 事务隔离级别下 其利用快照读 解决了 non-repeatable-read 的并发事务问题;

 

read view : https://dev.mysql.com/doc/refman/5.7/en/glossary.html#glos_read_view

snapshot : https://dev.mysql.com/doc/refman/5.7/en/glossary.html#glos_snapshot

 

快照读:

read view : 对于read view 在不同的事务隔离级别下其实现方式并不相同,read view 会在 read uncommitted /read committed / repeatable read 隔离级别下被创建

当前只针对 repeatable-read 隔离级别下 read view 生成策略 (以下使用 rr 表示 repeatable read )

对于启动快照读有两种方式

  1. start transaction with consistent snapshot 会立即创建 read view 
  2. 在事务启动后 第一次读取操作执行时才创建read view

对于read view 其基于 MVCC consistent read 要求, 在 rr级别下,创建的 read view 是基于整张表的, 里面存储的数据为 每一行的最新已提交事务id(低水位),当前事务开启时其他未提交的事务id(最大的事务id称为高水位);可以通过事务id查询 undo_log 日志来查询历史数据;

对于 rr 可见性控制实现, 主要是针对 同一时间未提交的事务判断,对于在 read view 正式创建前提交的事务是可见的,对于read view 创建后 已提交或未提交的事务都不会影响已创建的read view 数据

 

当前读:

对于当前读 的操作方式存在一下两种操作 

https://dev.mysql.com/doc/refman/5.7/en/innodb-locking-reads.html

  1. select ... for update : 锁的表现形式和 update 语句一样
  2. select ... lock in share mode : 对于当前操作支持 再次读取操作(读锁之间并不互斥,支持重进入),但对于其他事务的更新操作会被阻塞(读锁/写锁之间会互斥),需要等待当前事务提交后才可以执行修改操作

对于以上两种读加锁情况,不能开启自动提交(通过 set autocommit = 0 来关闭自动提交,或设置 set autocommit = 1 ),需要手动开启事务 以及手动提交或回滚事务;

对于 set autcommit = 0 和 set autocommit  = 1 的区别为

  • set autocommit = 0 模式下,执行任何语句(即使是select)都会开启一个事务,都需要手动 commit 或 rollback
  • set autocommit = 1 模式下, 必须使用 begin 或 start transaction 来开启事务

 

对于当前读的理解:

主要是针对更新操作(或具有更新操作特性的操作)而言,对于所有的更新操作(先读(当前读)后写)都需要先读取到当前行数据即时状态的持久化数据(事务已提交的数据),否则就有可能导致当前事务操作覆盖了之前事务的操作 

 

读锁统一的特点为 读锁之间的不会互斥,读锁和写锁之间会互斥

 

区别点:

对于当前读和快照读的区别在于,当前读 读取当前行数据最新的已提交的事务数据,并不受read view 的影响 

 

 

posted @ 2020-12-18 11:48  郭星  阅读(912)  评论(0)    收藏  举报