在进行多事务,并发读写的管理时,Mysql的InnoDB引擎采用的是Multiversion Concurrency Control机制,MVCC机制也被其他数据库所采用。每种引擎实现MVCC机制的具体细节不同,但大体思想类似。因此了解其思想,结合场景去应用。

1、MVCC机制是行级锁的一种妥协,多线程事务读取时,避免使用锁,而是采用一种更小的开销,允许非阻塞读取,写操作进行时只锁定必要的记录

2、简单的实现方式:MVCC保存某个时间点上的数据快照。一个事务内,看到的是同一个版本的快照,数据一致。不同事务在同一时间点看到的数据会不一致,因为他们得到的数据版本不一样。InnoDB在每一行记录添加两个额外的隐藏值,分别记录创建时间,和过期(或者删除)时间,这里的时间并不是真正意义上的时分秒,而是事件发生时数据库记录的系统版本号。

(1)每个事务创建时,Innodb的系统版本号会增加,而事务会记录这个作为自己的版本号,如上所述,每条数据库记录会保存两个版本号,一个是创建,一个是过期。当进行查询操作时,遵循两个原则:
     a.满足查询条件的记录,其创建版本号必须不大于事务版本,这样保证数据是事务开始前创建
        b.过期版本必须是未定义或者大于事务版本,开始后才过期,这样的数据是可读的。
(2)当一个事务修改了数据之后,数据的版本号会变化。其他事务就不会读取修改后的数据,因为和它们创建时获取的版本号不一致。
insert:InnoDB为这个新行记录当前的系统版本号;
delete:InnoDB将当前的系统版本号设置为这一行的删除ID;
update:InnoDB会写一个这行数据的新拷贝,这个拷贝为当前的系统版本号。同时将这个版本号写到旧行的过期时间中
(3)优点在于,大多数查询不需要获取额外的锁。但是Innodb会为每一行存储多个版本的数据。原理类似于copyonwrie
(4)可以解决脏读和不可重复读的问题,但是解决不了幻读的问题。脏读就是,事务A读取一个事务B没提交的数据,然后事务B回滚了。MVCC保证事务A读取的肯定是上一个版本的。不可重复读也是同理,事务A只读取其创建时的版本数据,其他事务对数据的修改只会得到新的版本数据。幻读解决不了是因为事务A更新所有数据,而事务B插入数据,但是由于版本问题事务A不能更新新插入的数据。