Mysql的隔离级别有四个
1、读未提交
2、读提交
3、可重复读 RR
4、串行读
隔离的实现
每次修改对应一个事务ID:row trx id,还对应一个undo log,因此undo log和row trx id是一一对应的。
当我们开始一个事务的时候,会生成一个事务的snap shot,将当前正在进行的没有提交的事务id存放到一个数组中。这个数组是静态的,可称之为视图。致性InnoDB就是用这个数组来实现隔离的,从而保证了一致性读。
数组中最大的ID是自己,表示高水位;最小的是事务id是低水位。
对于可重复读,小于低水位的数据说明在创建事务之前就已经提交,因此对于本事务是可见的;
大于高水位的数据是不可见的,是本次事务创建后才创建的事务修改的数据,因此对于本事务是不可见的;
如果处于低水位和高水位之前的事务修改的数据,则要看该事务id是否落在了视图创建是的事务数组中,如果落在了里面,表示虽然该事务早于我之前创建,但是晚于我事务启动时提交,因此是不可见的。如果没有落在事务id数组中,那么表示本事务创建时,该事务已经提交,因此是可见的。
以上几个原则,保证了一致性读。
更新操作的可见性
数据更新时,必须是在当前的最新的数据上修改,否则某些事务的更新就会被覆盖。因此,事务中的更新操作必须是当前读。这就和我们上面说的一致性读产生了矛盾,或者说是有别于一致性读。此时就要引入行锁,当数据修改,但没有提交时,行锁是一直持有的。因此其他事务的更新操作是会被阻塞的。因此,行锁保证了当前读,也就保证了数据的修改不会被覆盖。