ip反查域名网站,盐城网站推广电话,有口碑的网站建设公司,wordpress做多语言可重复读#xff08;repeatable read#xff09;定义#xff1a; 一个事务执行过程中看到的数据#xff0c;总是跟这个事务在启动时看到的数据是一致的。
MVCC MVCC#xff0c;多版本并发控制, 用于实现读已提交和可重复读隔离级别。 MVCC的核心就是 Undo log多版本链 …可重复读repeatable read定义 一个事务执行过程中看到的数据总是跟这个事务在启动时看到的数据是一致的。
MVCC MVCC多版本并发控制, 用于实现读已提交和可重复读隔离级别。 MVCC的核心就是 Undo log多版本链 Read view“MV”就是通过 Undo log来保存数据的历史版本实现多版本的管理“CC”是通过 Read-view来实现管理通过 Read-view原则来决定数据是否显示。同时针对不同的隔离级别 Read view的生成策略不同也就实现了不同的隔离级别。
Undo log 多版本链
每条数据都有两个隐藏字段: trx_id: 事务id,记录最近一次更新这条数据的事务id. roll_pointer: 回滚指针,指向之前生成的undo log 每一条数据都有多个版本,版本之间通过undo log链条进行连接通过这样的设计方式,可以保证每个事务提交的时候,一旦需要回滚操作,可以保证同一个事务只能读取到比当前版本更早提交的值,不能看到更晚提交的值。
ReadView
Read View是 InnoDB 在实现 MVCC 时用到的一致性读视图即 consistent read view用于支持 RCRead Committed读提交和 RRRepeatable Read可重复读隔离级别的实现.
Read View简单理解就是对数据在某个时刻的状态拍成照片记录下来。那么之后获取某时刻的数据时就还是原来的照片上的数据是不会变的.
Read View中比较重要的字段有4个: m_ids : 用来表示MySQL中哪些事务正在执行,但是没有提交. min_trx_id: 就是m_ids里最小的值. max_trx_id : 下一个要生成的事务id值,也就是最大事务id creator_trx_id: 就是你这个事务的id 当一个事务第一次执行查询sql时会生成一致性视图 read-view快照查询时从 undo log 中最新的一条记录开始跟 read-view 做对比如果不符合比较规则就根据回滚指针回滚到上一条记录继续比较直到得到符合比较条件的查询结果。
Read View判断记录某个版本是否可见的规则如下 1.如果当前记录的事务id落在绿色部分trx_id min_id表示这个版本是已提交的事务生成的可读。 2.如果当前记录的事务id落在红色部分trx_id max_id表示这个版本是由将来启动的事务生成的不可读。 如果当前记录的事务id落在黄色部分min_id trx_id max_id则分为两种情况 若当前记录的事务id在未提交事务的数组中则此条记录不可读 若当前记录的事务id不在未提交事务的数组中则此条记录可读。
RC 和 RR 隔离级别都是由 MVCC 实现区别在于 RC 隔离级别时read-view 是每次执行 select 语句时都生成一个 RR 隔离级别时read-view 是在第一次执行 select 语句时生成一个同一事务中后面的所有 select 语句都复用这个 read-view 。 Repeatable Read 解决了幻读问题吗
可重复读repeatable read定义 一个事务执行过程中看到的数据总是跟这个事务在启动时看到的数据是一致的。
不过理论上会出现幻读简单的说幻读指的的当用户读取某一范围的数据行时另一个事务又在该范围插入了新行当用户在读取该范围的数据时会发现有新的幻影行。
注意在可重复读隔离级别下普通的查询是快照读是不会看到别的事务插入的数据的。因此 幻读在“当前读”下才会出现查询语句添加for update表示当前读
在 MVCC 并发控制中读操作可以分为两类: 快照读Snapshot Read与当前读 Current Read。 快照读 快照读是指读取数据时不是读取最新版本的数据而是基于历史版本读取的一个快照信息mysql读取undo log历史版本) 快照读可以使普通的SELECT 读取数据时不用对表数据进行加锁从而解决了因为对数据库表的加锁而导致的两个如下问题 解决了因加锁导致的修改数据时无法对数据读取问题. 解决了因加锁导致读取数据时无法对数据进行修改的问题. 当前读 当前读是读取的数据库最新的数据当前读和快照读不同因为要读取最新的数据而且要保证事务的隔离性所以当前读是需要对数据进行加锁的插入/更新/删除操作属于当前读需要加锁 , select for update 为当前读
表结构
idkeyvalue000111
假设 select * from where value1 for update只在这一行加锁注意这只是假设其它行不加锁那么就会出现如下场景 Session A的三次查询Q1-Q3都是select * from where value1 for update查询的value1的所有row。 T1Q1只返回一行(1,1,1) T2session B更新id0的value为1此时表t中value1的数据有两行 T3Q2返回两行(0,0,1),(1,1,1) T4session C插入一行(6,6,1)此时表t中value1的数据有三行 T5Q3返回三行(0,0,1),(1,1,1),(6,6,1) T6session A事物commit。
其中Q3读到value1这一样的现象就称之为幻读幻读指的是一个事务在前后两次查询同一个范围的时候后一次查询看到了前一次查询没有看到的行。
先对“幻读”做出如下解释 要讨论「可重复读」隔离级别的幻读现象是要建立在「当前读」的情况下而不是快照读,因为在可重复读隔离级别下普通的查询是快照读是不会看到别的事务插入的数据的。
Next-key Lock 锁
产生幻读的原因是行锁只能锁住行但是新插入记录这个动作要更新的是记录之间的“间隙”。因此Innodb 引擎为了解决「可重复读」隔离级别使用「当前读」而造成的幻读问题就引出了 next-key 锁就是记录锁和间隙锁的组合。 RecordLock锁锁定单个行记录的锁。记录锁RC、RR隔离级别都支持 GapLock锁间隙锁锁定索引记录间隙(不包括记录本身)确保索引记录的间隙不变。范围锁RR隔离级别支持 Next-key Lock 锁记录锁和间隙锁组合同时锁住数据并且锁住数据前后范围。记录锁范围锁RR隔离级别支持 总结 RR隔离级别下间隙锁才有效RC隔离级别下没有间隙锁 RR隔离级别下为了解决“幻读”问题“快照读”依靠MVCC控制“当前读”通过间隙锁解决 间隙锁和行锁合称next-key lock每个next-key lock是前开后闭区间 间隙锁的引入可能会导致同样语句锁住更大的范围影响并发度。
知识来源马士兵教育