四种隔离级别的实现,其中串行化是强制事务串行处理,简单说,会在每一行数据上都加锁;脏读(未提交读)可以读取到未提交的数据,没啥可说的。
主要介绍下提交读和可重复读时如何实现的
事务隔离的实现:MVCC
InnoDB的mvcc:
1.事务启动时,InnoDB会分配每个事务递增且唯一的事务id,叫作 transaction id。
2.通过在每行记录后面保存两个隐藏的列,一个列创建此行的transaction id,一个保存删除此行的transaction id。
3.InnoDB只查找版本早于(包含等于)当前事务版本的数据行。可以确保事务读取的行,要么是事务开始前就已存在,或者事务自身插入或修改的记录;行的删除版本要么未定义,要么大于transaction id。可以确保事务读取的行,在事务开始之前未删除。
事务隔离的实现:Read View
但是上述实现解决不了一个问题:在可重复读的级别下,事务A先启动,但是未提交,事务A在事务B启动之后再提交,那么事务A修改的行按我们上面说的,事务B可以读到,实现不了可重复读啊。
Read View就是为了解决这个问题的:Read View就是事务进行快照读操作的时候生产的读视图,在该事务执行的快照读的那一刻,会生成数据库系统当前的一个快照(实现上是一个数组),记录并维护系统当前活跃事务的ID。“活跃”指的就是,启动了但还没提交。
在RC提交读隔离级别下,是每个快照读都会生成并获取最新的Read View;
在RR可重复读隔离级别下,则是同一个事务中的第一个快照读才会创建Read View, 之后的快照读获取的都是同一个Read View。
通过这个数组,过滤掉事务启动前未提交的事务。