做网站的公司有多少家,网站建设 网站专题 网络推广,网站 扁平化,网页编程html本文中用到的概念解释数据读取特性不可重复读指一个事务范围内两个相同的查询却返回了不同数据这是由于查询时系统中其他事务修改的提交而引起的幻读在两个连续的查找之间一个并发的修改事务修改了查询的数据集#xff0c;导致这两个查询返回了不同的结果这是由于查询时系统中…本文中用到的概念解释数据读取特性不可重复读指一个事务范围内两个相同的查询却返回了不同数据这是由于查询时系统中其他事务修改的提交而引起的幻读在两个连续的查找之间一个并发的修改事务修改了查询的数据集导致这两个查询返回了不同的结果这是由于查询时系统中其他事务新增或者删除记录引起的事务隔离级别Read Commited(提交读)一个事务从开始到提交前,所作的任何修改对其他事务不可见仅能读取到已提交的记录这种隔离级别下每条语句都会读取已提交事务的更新若两次查询之间有其他事务提交则会导致两次查询结果不一致。Repeatable Read(可重复读)在同一个事务中多次读取同样的记录的结果是一致的快照读与当前读在MVCC并发控制中读操作可以分成两类快照读与当前读快照读读取的是记录数据的可见版本(可能是过期的数据)不用加锁简单select使用该读取方式当前读读取的是记录数据的最新版本并且当前读返回的记录都会加上锁保证其他事务不会再并发的修改这条记录select ... lock in share modeselect ... for updateinsertupdatedelete以上查询将使用当前读什么是MVCC指多版本并发控制让普通的select语句直接读取指定版本的值避免加锁来提高并发请求时的性能配合行锁机制在并发请求下提高了MYSQL的性能MVCC解决了什么问题做到了读不影响写写不影响读提高了并发性能提供了一致性读的功能避免幻读和不可重复读什么时候会用到MVCC在RC和RR隔离级别下innodb通过快照读方式读取数据时使用MVCC实现原理通过保存数据在某个时间点的快照来实现具有以下两个特点不管执行多长时间同一个事务在执行的过程中看到的数据是一致的根据事务的开始时间不同不同事务的对同一张表同一时刻看到的数据可能是不一样的MVCC具体实现隐藏列innodb行都设置了隐藏列(对查询不可见)和MVCC有关的包含如下DATA_TRX_ID 产生这条记录的事务IDINSERT/UPDATE/DELETE时都会更新这个记录DATA_ROLL_PTR 指向该行回滚段的指针该行上所有旧的版本在undo中都通过链表的形式组织该值指向undo中下一个历史记录历史记录按照由新到旧顺序排列DELETED BIT位删除标志0或者1事务链表(当前活跃链表)MySQL中的事务在开始到提交这段过程中都会被保存到一个叫trx_sys的全局事务链表中这是一个基本的链表结构事务链表中保存的都是还未提交的事务事务一旦被提交则会被从事务链表中摘除ReadView在SQL开始的时候被创建的一个数据结构包含以下三个low_limit_id 表示该SQL启动时当前事务链表中最大的事务id编号也就是最近创建的除自身以外最大事务编号up_limit_id 表示该SQL启动时当前事务链表中最小的事务id编号也就是当前系统中创建最早但还未提交的事务trx_ids 存储当前trx_sys事务链表中的事务id集合。数据读取规则逻辑图流程描述先根据DATA_TRX_IDReadView 判断记录可见性如果可见根据 DELETED 判断数据是否删除如果不可见根据 DATA_ROLL_PTR 判断是否有历史版本没有则结束如果有则取出历史版本重新执行这个流程直到找到可见数据或者检查完所有历史版本如何判断可见性DATA_TRX_ID小于up_limit_id说明在事务开始前已经提交完成的数据对于当前事务来说是可见的DATA_TRX_ID大于low_limit_id说明在查询的时候这条数据还没有提交不可见DATA_TRX_ID位于up_limit_id和low_limit_id之间遍历ReadView中的trx_ids判断DATA_TRX_ID是否在其中如果不在表示事务已提交数据可见如果在表示事务未提交数据不可见MVCC是如何解决幻读和不可重复读问题的关键在于创建ReadView的时机在RC隔离级别下单个事务每次执行SELECT语句时都会创建ReadView所以两个相同条件的查询可能由于随着时间的推移ReadView更新后可以看到更多已提交的数据导致不可重复读和幻读在RR隔离级别下单个事务只会在第一次执行SELECT查询时创建ReadView后续不再更新所以整个事务期间可以看到的数据都是相同的不会出现不可重复读和幻读